Commit a84b36e3 authored by Grigory Fedorov's avatar Grigory Fedorov

Merge branch 'feature/chat_scroll_indicator' into develop

parents bd8c40df 4a6c5b6a
......@@ -8,8 +8,8 @@ android {
applicationId "com.xabber.androiddev"
minSdkVersion 14
targetSdkVersion 21
versionCode 130
versionName '0.10.31'
versionCode 131
versionName '0.10.32'
}
buildTypes {
......
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License,
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.data.extension.avatar;
import com.xabber.android.data.Application;
import com.xabber.android.data.account.AccountManager;
/**
* Set of default account's avatars.
*
* @author alexander.ivanov
*/
public class AccountAvatarSet extends BaseAvatarSet {
public AccountAvatarSet(Application application, int array,
int defaultDrawable) {
super(application, array, defaultDrawable);
}
@Override
protected int getIndex(String user) {
return AccountManager.getInstance().getColorLevel(user);
}
}
......@@ -17,8 +17,11 @@ package com.xabber.android.data.extension.avatar;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import com.xabber.android.data.Application;
import com.xabber.android.data.OnLoadListener;
......@@ -111,8 +114,8 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
private AvatarManager() {
this.application = Application.getInstance();
userAvatarSet = new BaseAvatarSet(application, R.array.default_avatars, R.drawable.avatar_1_1);
roomAvatarSet = new BaseAvatarSet(application, R.array.muc_avatars, R.drawable.avatar_muc_1);
userAvatarSet = new BaseAvatarSet(application, R.array.default_avatars_icons, R.array.default_avatars_colors);
roomAvatarSet = new BaseAvatarSet(application, R.array.muc_avatars, R.array.default_avatars_colors);
hashes = new HashMap<>();
bitmaps = new HashMap<>();
contactListDrawables = new HashMap<>();
......@@ -266,7 +269,7 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
if (value != null) {
return new BitmapDrawable(application.getResources(), value);
} else {
return application.getResources().getDrawable(R.drawable.ic_avatar_account);
return application.getResources().getDrawable(R.drawable.ic_avatar_1);
}
}
......@@ -281,10 +284,19 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
if (value != null) {
return new BitmapDrawable(application.getResources(), value);
} else {
return application.getResources().getDrawable(userAvatarSet.getResourceId(user));
return getDefaultAvatarDrawable(userAvatarSet.getResourceId(user));
}
}
private Drawable getDefaultAvatarDrawable(BaseAvatarSet.DefaultAvatar defaultAvatar) {
Drawable[] layers = new Drawable[2];
layers[0] = new ColorDrawable(defaultAvatar.getBackgroundColor());
layers[1] = application.getResources().getDrawable(defaultAvatar.getIconResource());
return new LayerDrawable(layers);
}
/**
* Gets bitmap with avatar for regular user.
*
......@@ -296,8 +308,14 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
if (value != null) {
return value;
} else {
return ((BitmapDrawable) application.getResources().getDrawable(
userAvatarSet.getResourceId(user))).getBitmap();
Drawable drawable = getDefaultAvatarDrawable(userAvatarSet.getResourceId(user));
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
......@@ -323,7 +341,7 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
* @return
*/
public Drawable getRoomAvatar(String user) {
return application.getResources().getDrawable(roomAvatarSet.getResourceId(user));
return getDefaultAvatarDrawable(roomAvatarSet.getResourceId(user));
}
/**
......@@ -358,7 +376,7 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
* @return
*/
public Drawable getOccupantAvatar(String user) {
return application.getResources().getDrawable(userAvatarSet.getResourceId(user));
return getDefaultAvatarDrawable(userAvatarSet.getResourceId(user));
}
/**
......
......@@ -14,14 +14,14 @@
*/
package com.xabber.android.data.extension.avatar;
import java.util.HashMap;
import java.util.Map;
import android.content.res.TypedArray;
import com.xabber.android.data.Application;
import com.xabber.android.data.OnLowMemoryListener;
import java.util.HashMap;
import java.util.Map;
/**
* Set of default avatars.
* <p/>
......@@ -33,22 +33,45 @@ public class BaseAvatarSet implements OnLowMemoryListener {
/**
* Default resources.
*/
private final int[] AVATARS;
private final int[] avatarIconsResources;
private final int[] colors;
/**
* Map with resource ids for specified uses.
*/
private final Map<String, Integer> resources;
public BaseAvatarSet(Application application, int array, int defaultDrawable) {
TypedArray defaultAvatars = application.getResources()
.obtainTypedArray(array);
AVATARS = new int[defaultAvatars.length()];
for (int index = 0; index < defaultAvatars.length(); index++)
AVATARS[index] = defaultAvatars.getResourceId(index,
defaultDrawable);
private final Map<String, DefaultAvatar> resources;
public static class DefaultAvatar {
public DefaultAvatar(int iconResource, int backgroundColor) {
this.iconResource = iconResource;
this.backgroundColor = backgroundColor;
}
public int getIconResource() {
return iconResource;
}
public int getBackgroundColor() {
return backgroundColor;
}
private int iconResource;
private int backgroundColor;
}
public BaseAvatarSet(Application application, int avatarIconsArrayId, int avatarColorsArrayId) {
TypedArray defaultAvatars = application.getResources().obtainTypedArray(avatarIconsArrayId);
avatarIconsResources = new int[defaultAvatars.length()];
for (int index = 0; index < defaultAvatars.length(); index++) {
avatarIconsResources[index] = defaultAvatars.getResourceId(index, -1);
}
defaultAvatars.recycle();
resources = new HashMap<String, Integer>();
colors = application.getResources().getIntArray(avatarColorsArrayId);
resources = new HashMap<>();
}
/**
......@@ -67,13 +90,13 @@ public class BaseAvatarSet implements OnLowMemoryListener {
* @param user
* @return
*/
public int getResourceId(String user) {
Integer resource = resources.get(user);
if (resource == null) {
resource = getElement(getIndex(user), AVATARS);
resources.put(user, resource);
public DefaultAvatar getResourceId(String user) {
DefaultAvatar avatar = resources.get(user);
if (avatar == null) {
avatar = getElement(getIndex(user));
resources.put(user, avatar);
}
return resource;
return avatar;
}
/**
......@@ -83,11 +106,16 @@ public class BaseAvatarSet implements OnLowMemoryListener {
* @param array
* @return Always return element even if array's length is less then index.
*/
private int getElement(int index, int[] array) {
index = index % array.length;
if (index < 0)
index += array.length;
return array[index];
private DefaultAvatar getElement(int index) {
int uniqueCombinationsNumber = avatarIconsResources.length * colors.length;
index = index % uniqueCombinationsNumber;
if (index < 0) {
index += uniqueCombinationsNumber;
}
return new DefaultAvatar(avatarIconsResources[index / colors.length], colors[index % colors.length]);
}
@Override
......
......@@ -27,6 +27,7 @@ import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.xabber.android.data.ActivityManager;
import com.xabber.android.data.Application;
......@@ -50,6 +51,7 @@ import com.xabber.android.data.notification.NotificationManager;
import com.xabber.android.data.roster.AbstractContact;
import com.xabber.android.data.roster.OnContactChangedListener;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.android.ui.adapter.ChatScrollIndicatorAdapter;
import com.xabber.android.ui.adapter.ChatViewerAdapter;
import com.xabber.android.ui.dialog.ChatExportDialogFragment;
import com.xabber.android.ui.helper.ContactTitleActionBarInflater;
......@@ -85,6 +87,7 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
private String extraText = null;
ChatScrollIndicatorAdapter chatScrollIndicatorAdapter;
ChatViewerAdapter chatViewerAdapter;
ViewPager viewPager;
......@@ -144,6 +147,10 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
isChatSelected = false;
}
chatScrollIndicatorAdapter = new ChatScrollIndicatorAdapter(this,
(LinearLayout)findViewById(R.id.chat_scroll_indicator));
chatScrollIndicatorAdapter.update(chatViewerAdapter.getRealCount());
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(chatViewerAdapter);
viewPager.setOnPageChangeListener(this);
......@@ -284,6 +291,7 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
return;
chatViewerAdapter.updateChats();
chatScrollIndicatorAdapter.update(chatViewerAdapter.getRealCount());
String account = getAccount(intent);
String user = getUser(intent);
......@@ -292,6 +300,7 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
}
selectPage(account, user, false);
}
@Override
......@@ -539,6 +548,8 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
if (chatViewerAdapter.updateChats()) {
selectPage(currentAccount, currentUser, false);
chatScrollIndicatorAdapter.update(chatViewerAdapter.getRealCount());
} else {
updateRegisteredChats();
updateRegisteredRecentChatsFragments();
......@@ -605,6 +616,7 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
hideKeyboard(this);
AbstractChat selectedChat = chatViewerAdapter.getChatByPageNumber(position);
chatScrollIndicatorAdapter.select(chatViewerAdapter.getRealPagePosition(position));
isChatSelected = selectedChat != null;
......
......@@ -63,7 +63,7 @@ public class RecentChatFragment extends ListFragment {
activity.finish();
}
return inflater.inflate(R.layout.list, container, false);
return inflater.inflate(R.layout.recent_chats, container, false);
}
@Override
......
package com.xabber.android.ui.adapter;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import com.xabber.androiddev.R;
public class ChatScrollIndicatorAdapter {
private final Activity activity;
private final LinearLayout linearLayout;
public ChatScrollIndicatorAdapter(Activity activity, LinearLayout linearLayout) {
this.activity = activity;
this.linearLayout = linearLayout;
}
public void select(int selectedPosition) {
for (int index = 0; index < linearLayout.getChildCount(); index++) {
final View view = linearLayout.getChildAt(index);
final AccountViewHolder accountViewHolder = (AccountViewHolder) view.getTag();
accountViewHolder.selection.setVisibility(index == selectedPosition ? View.VISIBLE : View.GONE);
accountViewHolder.body.setVisibility(index == selectedPosition ? View.GONE : View.VISIBLE);
}
}
public void update(int size) {
final LayoutInflater inflater
= (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
while (linearLayout.getChildCount() < size) {
final View view = inflater.inflate(R.layout.chat_scroll_indicator_item, linearLayout, false);
linearLayout.addView(view);
final AccountViewHolder accountViewHolder = new AccountViewHolder(view);
view.setTag(accountViewHolder);
}
while (linearLayout.getChildCount() > size) {
linearLayout.removeViewAt(size);
}
}
private static class AccountViewHolder {
final View body;
final View selection;
public AccountViewHolder(View view) {
body = view.findViewById(R.id.indicator_item_body);
selection = view.findViewById(R.id.indicator_item_selection);
}
}
}
......@@ -144,7 +144,7 @@ public class ChatViewerAdapter extends FragmentStatePagerAdapter {
}
private int getRealPagePosition(int virtualPosition) {
public int getRealPagePosition(int virtualPosition) {
int realCount = getRealCount();
int pageNumber = abs(virtualPosition - OFFSET) % realCount;
......@@ -194,4 +194,5 @@ public class ChatViewerAdapter extends FragmentStatePagerAdapter {
public Fragment getCurrentFragment() {
return currentFragment;
}
}
\ No newline at end of file
......@@ -35,7 +35,7 @@
android:id="@+id/avatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_avatar_account" />
android:src="@drawable/ic_avatar_1" />
</RelativeLayout>
<TextView
android:id="@+id/name"
......
......@@ -24,7 +24,7 @@
android:layout_height="32dip"
android:layout_marginTop="4dip"
android:layout_marginLeft="4dip"
android:src="@drawable/ic_avatar_account"
android:src="@drawable/ic_avatar_1"
/>
<ImageView
android:id="@+id/status_mode"
......
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:id="@+id/chat_scroll_indicator"
>
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
......@@ -17,5 +17,5 @@
android:id="@+id/avatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_avatar_account" />
android:src="@drawable/ic_avatar_1" />
</RelativeLayout>
\ No newline at end of file
......@@ -36,7 +36,7 @@
android:layout_width="@dimen/avatar_size"
android:layout_height="@dimen/avatar_size"
android:layout_toRightOf="@id/color"
android:src="@drawable/avatar_1_1"
android:src="@drawable/ic_avatar_1"
/>
<RelativeLayout
......
......@@ -37,7 +37,7 @@
android:layout_width="@dimen/avatar_size"
android:layout_height="@dimen/avatar_size"
android:layout_toRightOf="@id/color"
android:src="@drawable/avatar_1_1"
android:src="@drawable/ic_avatar_1"
/>
<LinearLayout
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="3dp"
android:layout_marginRight="3dp"
android:layout_marginLeft="3dp"
android:layout_marginStart="3dp"
>
<ImageView
android:id="@+id/indicator_item_body"
android:layout_width="6dp"
android:layout_height="6dp"
android:layout_margin="2dp"
android:background="@color/grey_500"
/>
<View
android:id="@+id/indicator_item_selection"
android:layout_width="10dp"
android:layout_height="10dp"
android:background="@color/grey_500"
android:visibility="gone"
/>
</RelativeLayout>
\ No newline at end of file
......@@ -31,7 +31,7 @@
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:src="@drawable/avatar_1_1"
android:src="@drawable/ic_avatar_1"
/>
<TextView
......
......@@ -13,7 +13,7 @@
android:id="@+id/avatar"
android:layout_width="48dip"
android:layout_height="48dip"
android:src="@drawable/avatar_1_1"
android:src="@drawable/ic_avatar_1"
android:layout_gravity="center_vertical"
android:layout_marginRight="4dp"
android:layout_marginEnd="4dp"
......
......@@ -28,7 +28,7 @@
android:id="@+id/avatar"
android:layout_width="@dimen/avatar_size"
android:layout_height="@dimen/avatar_size"
android:src="@drawable/avatar_1_1"
android:src="@drawable/ic_avatar_1"
/>
<ImageView
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@android:id/list"
android:layout_marginTop="15dp"
/>
</LinearLayout>
\ No newline at end of file
......@@ -13,57 +13,25 @@
along with this program. If not, see http://www.gnu.org/licenses/.
-->
<resources>
<array name="default_avatars">
<item>@drawable/avatar_1_1</item>
<item>@drawable/avatar_1_2</item>
<item>@drawable/avatar_1_3</item>
<item>@drawable/avatar_1_4</item>
<item>@drawable/avatar_1_5</item>
<item>@drawable/avatar_1_6</item>
<item>@drawable/avatar_1_7</item>
<item>@drawable/avatar_1_8</item>
<item>@drawable/avatar_2_1</item>
<item>@drawable/avatar_2_2</item>
<item>@drawable/avatar_2_3</item>
<item>@drawable/avatar_2_4</item>
<item>@drawable/avatar_2_5</item>
<item>@drawable/avatar_2_6</item>
<item>@drawable/avatar_2_7</item>
<item>@drawable/avatar_3_8</item>
<item>@drawable/avatar_3_1</item>
<item>@drawable/avatar_3_2</item>
<item>@drawable/avatar_3_3</item>
<item>@drawable/avatar_3_4</item>
<item>@drawable/avatar_3_5</item>
<item>@drawable/avatar_3_6</item>
<item>@drawable/avatar_3_7</item>
<item>@drawable/avatar_3_8</item>
<item>@drawable/avatar_4_1</item>
<item>@drawable/avatar_4_2</item>
<item>@drawable/avatar_4_3</item>
<item>@drawable/avatar_4_4</item>
<item>@drawable/avatar_4_5</item>
<item>@drawable/avatar_4_6</item>
<item>@drawable/avatar_4_7</item>
<item>@drawable/avatar_4_8</item>
<item>@drawable/avatar_5_1</item>
<item>@drawable/avatar_5_2</item>
<item>@drawable/avatar_5_3</item>
<item>@drawable/avatar_5_4</item>
<item>@drawable/avatar_5_5</item>
<item>@drawable/avatar_5_6</item>
<item>@drawable/avatar_5_7</item>
<item>@drawable/avatar_5_8</item>
<item>@drawable/avatar_6_1</item>
<item>@drawable/avatar_6_2</item>
<item>@drawable/avatar_6_3</item>
<item>@drawable/avatar_6_4</item>
<item>@drawable/avatar_6_5</item>
<item>@drawable/avatar_6_6</item>
<item>@drawable/avatar_6_7</item>
<item>@drawable/avatar_6_8</item>
<array name="default_avatars_icons">
<item>@drawable/ic_avatar_1</item>
<item>@drawable/ic_avatar_2</item>
<item>@drawable/ic_avatar_5</item>
<item>@drawable/ic_avatar_3</item>
<item>@drawable/ic_avatar_4</item>
</array>
<array name="default_avatars_colors">
<item>@color/light_green_500</item>
<item>@color/light_blue_500</item>
<item>@color/indigo_500</item>
<item>@color/purple_500</item>
<item>@color/red_900</item>
<item>@color/orange_700</item>
<item>@color/amber_500</item>
</array>
<array name="muc_avatars">
<item>@drawable/avatar_muc_1</item>
<item>@drawable/avatar_muc_2</item>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment