Auto-scroll navigation view to make selected item always visible
* Set order # to each selectable menu item (i.e. excluding Settings and
Help&feedback) so that we know scroll position. The order # is based
on # of groups and # of filters.
* Update scroll position when we set selection status of menu items.
* Scroll to the position with an offset so that the visible item appear
in the middle of the screen (in fact 1/3 height of the screen).
* Modify the way to make status bar transparent so that it's transparent
in the new green duplicates activity.
Bug 29792209
Change-Id: I9dddc6cceeed835eaf7e7157cc7bad0adb24b1ff
diff --git a/src/com/android/contacts/ContactsDrawerActivity.java b/src/com/android/contacts/ContactsDrawerActivity.java
index e4f8010..cf44fe3 100644
--- a/src/com/android/contacts/ContactsDrawerActivity.java
+++ b/src/com/android/contacts/ContactsDrawerActivity.java
@@ -32,7 +32,10 @@
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -95,6 +98,13 @@
protected static final String ACTION_CREATE_GROUP = "createGroup";
+ // TODO(wenyiw): remove all the code related to these constants after switching to fragments.
+ // Positions of "all contacts" and "duplicates" in navigation drawer.
+ private static final int ALL_CONTACTS_POSITION = 1;
+ private static final int DUPLICATES_POSITION = 2;
+ // Gap between two menu groups, including a separator, a menu group header.
+ private static final int GAP_BETWEEN_TWO_MENU_GROUPS = 2;
+
private class ContactsActionBarDrawerToggle extends ActionBarDrawerToggle {
private Runnable mRunnable;
@@ -153,6 +163,8 @@
// The account the new group will be created under.
private AccountWithDataSet mNewGroupAccount;
+ private int mPositionOfLastGroup;
+
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
@@ -202,6 +214,7 @@
clearCheckedMenus();
mIdMenuMap.get(R.id.nav_find_duplicates).setCheckable(true);
mIdMenuMap.get(R.id.nav_find_duplicates).setChecked(true);
+ updateScrollPosition(DUPLICATES_POSITION);
}
if (savedState != null && savedState.containsKey(KEY_NEW_GROUP_ACCOUNT)) {
@@ -210,6 +223,20 @@
}
}
+ private void updateScrollPosition(int position) {
+ final RecyclerView recyclerView = (RecyclerView) mNavigationView.getChildAt(0);
+ final LinearLayoutManager layoutManager =
+ (LinearLayoutManager) recyclerView.getLayoutManager();
+
+ // Get screen height
+ final DisplayMetrics metrics = getResources().getDisplayMetrics();
+ final int height = metrics.heightPixels;
+
+ // Set 1/3 screen height as offset if possible.
+ layoutManager.scrollToPositionWithOffset(position, height / 3);
+ recyclerView.requestLayout();
+ }
+
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@@ -227,9 +254,10 @@
}
private void makeStatusBarTransparent() {
- if (CompatUtils.isLollipopCompatible()
- && getWindow().getStatusBarColor() ==
- ContextCompat.getColor(this, R.color.primary_color_dark)) {
+ // Avoid making status bar transparent when action bar's selection mode is on.
+ if (getWindow().getStatusBarColor() !=
+ ContextCompat.getColor(this, R.color.contextual_selection_bar_status_bar_color)
+ && CompatUtils.isLollipopCompatible()) {
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
}
@@ -312,15 +340,18 @@
subMenu.removeGroup(R.id.nav_groups_items);
mGroupMenuMap = new HashMap<>();
+ mPositionOfLastGroup = DUPLICATES_POSITION + GAP_BETWEEN_TWO_MENU_GROUPS;
+
if (groupListItems != null) {
// Add each group
for (final GroupListItem groupListItem : groupListItems) {
if (GroupUtil.isEmptyFFCGroup(groupListItem)) {
continue;
}
+ mPositionOfLastGroup++;
final String title = groupListItem.getTitle();
final MenuItem menuItem =
- subMenu.add(R.id.nav_groups_items, Menu.NONE, Menu.NONE, title);
+ subMenu.add(R.id.nav_groups_items, Menu.NONE, mPositionOfLastGroup, title);
mGroupMenuMap.put(groupListItem.getGroupId(), menuItem);
menuItem.setIcon(R.drawable.ic_menu_label);
menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@@ -345,9 +376,10 @@
return;
}
+ mPositionOfLastGroup++;
// Create a menu item in the sub menu to add new groups
- final MenuItem menuItem = subMenu.add(R.id.nav_groups_items, Menu.NONE, Menu.NONE,
- getString(R.string.menu_new_group_action_bar));
+ final MenuItem menuItem = subMenu.add(R.id.nav_groups_items, Menu.NONE,
+ mPositionOfLastGroup, getString(R.string.menu_new_group_action_bar));
menuItem.setIcon(R.drawable.ic_add);
menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
@@ -374,6 +406,7 @@
&& mGroupMenuMap.get(groupMetadata.groupId) != null) {
mGroupMenuMap.get(groupMetadata.groupId).setCheckable(true);
mGroupMenuMap.get(groupMetadata.groupId).setChecked(true);
+ updateScrollPosition(mGroupMenuMap.get(groupMetadata.groupId).getOrder());
}
}
@@ -420,13 +453,16 @@
return;
}
+ int positionOfLastFilter = mPositionOfLastGroup + GAP_BETWEEN_TWO_MENU_GROUPS;
+
for (int i = 0; i < accountFilterItems.size(); i++) {
+ positionOfLastFilter++;
final ContactListFilter filter = accountFilterItems.get(i);
final String menuName =
filter.filterType == ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS
? getString(R.string.account_phone) : filter.accountName;
- final MenuItem menuItem = subMenu.add(R.id.nav_filters_items, Menu.NONE, Menu.NONE,
- menuName);
+ final MenuItem menuItem = subMenu.add(R.id.nav_filters_items, Menu.NONE,
+ positionOfLastFilter, menuName);
mFilterMenuMap.put(filter, menuItem);
final Intent intent = new Intent();
intent.putExtra(AccountFilterUtil.EXTRA_CONTACT_LIST_FILTER, filter);
@@ -449,7 +485,7 @@
}
});
menuItem.setIcon(filter.icon);
- // Get rid of the default memu item overlay and show original account icons.
+ // Get rid of the default menu item overlay and show original account icons.
menuItem.getIcon().setColorFilter(Color.TRANSPARENT, PorterDuff.Mode.SRC_ATOP);
}
@@ -464,11 +500,13 @@
if (mIdMenuMap != null && mIdMenuMap.get(R.id.nav_all_contacts) != null) {
mIdMenuMap.get(R.id.nav_all_contacts).setCheckable(true);
mIdMenuMap.get(R.id.nav_all_contacts).setChecked(true);
+ updateScrollPosition(ALL_CONTACTS_POSITION);
}
} else {
if (mFilterMenuMap != null && mFilterMenuMap.get(filter) != null) {
mFilterMenuMap.get(filter).setCheckable(true);
mFilterMenuMap.get(filter).setChecked(true);
+ updateScrollPosition(mFilterMenuMap.get(filter).getOrder());
}
}
}