Improve Phone UI's horizontal swipe behavior
- fix an obvious bug in PhoneFavoriteFragment, with which sort-order and
display-order preserved by the "all" adapter are just ignored. Because
of that the whole "all-contacts" section has been loaded every time
when its View is recreated.
- stop creating two Adapters on PhoneFavoriteFragment#onCreateView(),
which will cause unnecessary reload of those adapters.
- use ViewPager#setOffsreenPageLimit(2) to keep all the three fragments
during user's interaction.
Bug: 6005454
Change-Id: I8769eeba7e5568afedea097b2d388c6ed93fcf40
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index 4089434..ae8fe09 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -497,6 +497,7 @@
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(new ViewPagerAdapter(getFragmentManager()));
mViewPager.setOnPageChangeListener(mPageChangeListener);
+ mViewPager.setOffscreenPageLimit(2);
// Do same width calculation as ActionBar does
DisplayMetrics dm = getResources().getDisplayMetrics();
diff --git a/src/com/android/contacts/list/PhoneFavoriteFragment.java b/src/com/android/contacts/list/PhoneFavoriteFragment.java
index 2e62d1a..011a811 100644
--- a/src/com/android/contacts/list/PhoneFavoriteFragment.java
+++ b/src/com/android/contacts/list/PhoneFavoriteFragment.java
@@ -237,10 +237,57 @@
private final ScrollListener mScrollListener = new ScrollListener();
@Override
+ public void onAttach(Activity activity) {
+ if (DEBUG) Log.d(TAG, "onAttach()");
+ super.onAttach(activity);
+
+ mContactsPrefs = new ContactsPreferences(activity);
+
+ // Construct two base adapters which will become part of PhoneFavoriteMergedAdapter.
+ // We don't construct the resultant adapter at this moment since it requires LayoutInflater
+ // that will be available on onCreateView().
+
+ mContactTileAdapter = new ContactTileAdapter(activity, mContactTileAdapterListener,
+ getResources().getInteger(R.integer.contact_tile_column_count),
+ ContactTileAdapter.DisplayType.STREQUENT_PHONE_ONLY);
+ mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
+
+ // Setup the "all" adapter manually. See also the setup logic in ContactEntryListFragment.
+ mAllContactsAdapter = new PhoneNumberListAdapter(activity);
+ mAllContactsAdapter.setDisplayPhotos(true);
+ mAllContactsAdapter.setQuickContactEnabled(true);
+ mAllContactsAdapter.setSearchMode(false);
+ mAllContactsAdapter.setIncludeProfile(false);
+ mAllContactsAdapter.setSelectionVisible(false);
+ mAllContactsAdapter.setDarkTheme(true);
+ mAllContactsAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
+ // Disable directory header.
+ mAllContactsAdapter.setHasHeader(0, false);
+ // Show A-Z section index.
+ mAllContactsAdapter.setSectionHeaderDisplayEnabled(true);
+ // Disable pinned header. It doesn't work with this fragment.
+ mAllContactsAdapter.setPinnedPartitionHeadersEnabled(false);
+ // Put photos on left for consistency with "frequent" contacts section.
+ mAllContactsAdapter.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
+
+ // Use Callable.CONTENT_URI which will include not only phone numbers but also SIP
+ // addresses.
+ mAllContactsAdapter.setUseCallableUri(true);
+
+ mAllContactsAdapter.setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder());
+ mAllContactsAdapter.setSortOrder(mContactsPrefs.getSortOrder());
+ }
+
+ @Override
public void onCreate(Bundle savedState) {
+ if (DEBUG) Log.d(TAG, "onCreate()");
super.onCreate(savedState);
if (savedState != null) {
mFilter = savedState.getParcelable(KEY_FILTER);
+
+ if (mFilter != null) {
+ mAllContactsAdapter.setFilter(mFilter);
+ }
}
setHasOptionsMenu(true);
}
@@ -252,13 +299,6 @@
}
@Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
-
- mContactsPrefs = new ContactsPreferences(activity);
- }
-
- @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View listLayout = inflater.inflate(
@@ -271,7 +311,16 @@
mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
- initAdapters(getActivity(), inflater);
+ // Create the account filter header but keep it hidden until "all" contacts are loaded.
+ mAccountFilterHeaderContainer = new FrameLayout(getActivity(), null);
+ mAccountFilterHeader = inflater.inflate(R.layout.account_filter_header_for_phone_favorite,
+ mListView, false);
+ mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener);
+ mAccountFilterHeaderContainer.addView(mAccountFilterHeader);
+ mAccountFilterHeaderContainer.setVisibility(View.GONE);
+
+ mAdapter = new PhoneFavoriteMergedAdapter(getActivity(),
+ mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter);
mListView.setAdapter(mAdapter);
@@ -288,59 +337,6 @@
return listLayout;
}
- /**
- * Constructs and initializes {@link #mContactTileAdapter}, {@link #mAllContactsAdapter}, and
- * {@link #mAllContactsAdapter}.
- *
- * TODO: Move all the code here to {@link PhoneFavoriteMergedAdapter} if possible.
- * There are two problems: account header (whose content changes depending on filter settings)
- * and OnClickListener (which initiates {@link Activity#startActivityForResult(Intent, int)}).
- * See also issue 5429203, 5269692, and 5432286. If we are able to have a singleton for filter,
- * this work will become easier.
- */
- private void initAdapters(Context context, LayoutInflater inflater) {
- mContactTileAdapter = new ContactTileAdapter(context, mContactTileAdapterListener,
- getResources().getInteger(R.integer.contact_tile_column_count),
- ContactTileAdapter.DisplayType.STREQUENT_PHONE_ONLY);
- mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(context));
-
- // Setup the "all" adapter manually. See also the setup logic in ContactEntryListFragment.
- mAllContactsAdapter = new PhoneNumberListAdapter(context);
- mAllContactsAdapter.setDisplayPhotos(true);
- mAllContactsAdapter.setQuickContactEnabled(true);
- mAllContactsAdapter.setSearchMode(false);
- mAllContactsAdapter.setIncludeProfile(false);
- mAllContactsAdapter.setSelectionVisible(false);
- mAllContactsAdapter.setDarkTheme(true);
- mAllContactsAdapter.setPhotoLoader(ContactPhotoManager.getInstance(context));
- // Disable directory header.
- mAllContactsAdapter.setHasHeader(0, false);
- // Show A-Z section index.
- mAllContactsAdapter.setSectionHeaderDisplayEnabled(true);
- // Disable pinned header. It doesn't work with this fragment.
- mAllContactsAdapter.setPinnedPartitionHeadersEnabled(false);
- // Put photos on left for consistency with "frequent" contacts section.
- mAllContactsAdapter.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
-
- mAllContactsAdapter.setUseCallableUri(true);
-
- if (mFilter != null) {
- mAllContactsAdapter.setFilter(mFilter);
- }
-
- // Create the account filter header but keep it hidden until "all" contacts are loaded.
- mAccountFilterHeaderContainer = new FrameLayout(context, null);
- mAccountFilterHeader = inflater.inflate(R.layout.account_filter_header_for_phone_favorite,
- mListView, false);
- mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener);
- mAccountFilterHeaderContainer.addView(mAccountFilterHeader);
- mAccountFilterHeaderContainer.setVisibility(View.GONE);
-
- mAdapter = new PhoneFavoriteMergedAdapter(context,
- mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter);
-
- }
-
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
@@ -381,7 +377,7 @@
mAllContactsForceReload = true;
}
- // Use initLoader() instead of reloadLoader() to refraing unnecessary reload.
+ // Use initLoader() instead of restartLoader() to refraining unnecessary reload.
// This method call implicitly assures ContactTileLoaderListener's onLoadFinished() will
// be called, on which we'll check if "all" contacts should be reloaded again or not.
getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null, mContactTileLoaderListener);
@@ -431,13 +427,15 @@
}
boolean changed = false;
- if (mAllContactsAdapter.getContactNameDisplayOrder() != mContactsPrefs.getDisplayOrder()) {
- mAllContactsAdapter.setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder());
+ final int currentDisplayOrder = mContactsPrefs.getDisplayOrder();
+ if (mAllContactsAdapter.getContactNameDisplayOrder() != currentDisplayOrder) {
+ mAllContactsAdapter.setContactNameDisplayOrder(currentDisplayOrder);
changed = true;
}
- if (mAllContactsAdapter.getSortOrder() != mContactsPrefs.getSortOrder()) {
- mAllContactsAdapter.setSortOrder(mContactsPrefs.getSortOrder());
+ final int currentSortOrder = mContactsPrefs.getSortOrder();
+ if (mAllContactsAdapter.getSortOrder() != currentSortOrder) {
+ mAllContactsAdapter.setSortOrder(currentSortOrder);
changed = true;
}