PhoneFavoriteFragment.java revision aabc1e81c2d43827fe2ad0bdde6851bdfb431924
19b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa/* 29b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * Copyright (C) 2011 The Android Open Source Project 39b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * 49b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License"); 59b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * you may not use this file except in compliance with the License. 69b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * You may obtain a copy of the License at 79b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * 89b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * http://www.apache.org/licenses/LICENSE-2.0 99b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * 109b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * Unless required by applicable law or agreed to in writing, software 119b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS, 129b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * See the License for the specific language governing permissions and 149b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * limitations under the License. 159b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 169b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawapackage com.android.contacts.list; 179b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 189b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport com.android.contacts.ContactPhotoManager; 199b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport com.android.contacts.ContactTileLoaderFactory; 209b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport com.android.contacts.R; 217c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawaimport com.android.contacts.interactions.ImportExportDialogFragment; 229b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport com.android.contacts.preference.ContactsPreferences; 2334b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawaimport com.android.contacts.util.AccountFilterUtil; 249b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 259b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.app.Activity; 269b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.app.Fragment; 279b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.app.LoaderManager; 289b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.content.Context; 299b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.content.CursorLoader; 309b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.content.Intent; 319b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.content.Loader; 329b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.database.Cursor; 337a700cf798a19a8452b8671f643a05336f63f611Katherine Kuanimport android.graphics.Rect; 349b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.net.Uri; 359b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.os.Bundle; 367c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawaimport android.provider.ContactsContract; 379b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.provider.ContactsContract.Directory; 387c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawaimport android.provider.Settings; 399b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.util.Log; 409b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.view.LayoutInflater; 417c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawaimport android.view.Menu; 427c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawaimport android.view.MenuInflater; 437c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawaimport android.view.MenuItem; 449b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.view.View; 459b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.view.View.OnClickListener; 469b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.view.ViewGroup; 471dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawaimport android.widget.AbsListView; 489b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.widget.AdapterView; 499b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.widget.AdapterView.OnItemClickListener; 5034b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawaimport android.widget.FrameLayout; 519b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.widget.ListView; 529b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport android.widget.TextView; 539b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 549b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa/** 559b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * Fragment for Phone UI's favorite screen. 569b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * 579b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * This fragment contains three kinds of contacts in one screen: "starred", "frequent", and "all" 589b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * contacts. To show them at once, this merges results from {@link ContactTileAdapter} and 599b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * {@link PhoneNumberListAdapter} into one unified list using {@link PhoneFavoriteMergedAdapter}. 609b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * A contact filter header is also inserted between those adapters' results. 619b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 62091034c2d4c3ea69fc63c2e9d0956a109a13e08eDaisuke Miyakawapublic class PhoneFavoriteFragment extends Fragment implements OnItemClickListener { 639b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private static final String TAG = PhoneFavoriteFragment.class.getSimpleName(); 649b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private static final boolean DEBUG = false; 659b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 669b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 679b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * Used with LoaderManager. 689b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 699b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private static int LOADER_ID_CONTACT_TILE = 1; 709b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private static int LOADER_ID_ALL_CONTACTS = 2; 719b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 729b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private static final String KEY_FILTER = "filter"; 739b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 7434b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa private static final int REQUEST_CODE_ACCOUNT_FILTER = 1; 7534b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa 769b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public interface Listener { 779b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onContactSelected(Uri contactUri); 784e05a29c9b05c8cb74972aa5b9fe55fe35d7f45dJosh Gargus public void onCallNumberDirectly(String phoneNumber); 799b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 809b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 819b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> { 829b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 839b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public CursorLoader onCreateLoader(int id, Bundle args) { 849b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onCreateLoader."); 859b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return ContactTileLoaderFactory.createStrequentPhoneOnlyLoader(getActivity()); 869b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 879b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 889b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 899b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 909b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoadFinished"); 919b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactTileAdapter.setContactCursor(data); 929b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 939b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mAllContactsForceReload) { 949b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.onDataReload(); 959b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Use restartLoader() to make LoaderManager to load the section again. 969b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa getLoaderManager().restartLoader( 979b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener); 989b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } else if (!mAllContactsLoaderStarted) { 999b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Load "all" contacts if not loaded yet. 1009b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa getLoaderManager().initLoader( 1019b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener); 1029b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1039b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsForceReload = false; 1049b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsLoaderStarted = true; 1059b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1069b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Show the filter header with "loading" state. 1079b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa updateFilterHeaderView(); 10834b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa mAccountFilterHeader.setVisibility(View.VISIBLE); 1099b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1109b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1119b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1129b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onLoaderReset(Loader<Cursor> loader) { 1139b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoaderReset. "); 1149b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1159b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1169b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1179b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private class AllContactsLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> { 1189b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1199b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public Loader<Cursor> onCreateLoader(int id, Bundle args) { 1209b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onCreateLoader"); 1219b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa CursorLoader loader = new CursorLoader(getActivity(), null, null, null, null, null); 1229b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.configureLoader(loader, Directory.DEFAULT); 1239b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return loader; 1249b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1259b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1269b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1279b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 1289b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onLoadFinished"); 1299b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.changeCursor(0, data); 1309b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa updateFilterHeaderView(); 1319b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAccountFilterHeaderContainer.setVisibility(View.VISIBLE); 1329b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1339b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1349b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1359b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onLoaderReset(Loader<Cursor> loader) { 1369b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onLoaderReset. "); 1379b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1389b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1399b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1404e05a29c9b05c8cb74972aa5b9fe55fe35d7f45dJosh Gargus private class ContactTileAdapterListener implements ContactTileView.Listener { 1419b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1427a700cf798a19a8452b8671f643a05336f63f611Katherine Kuan public void onContactSelected(Uri contactUri, Rect targetRect) { 1439b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mListener != null) { 1449b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mListener.onContactSelected(contactUri); 1459b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1469b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1474e05a29c9b05c8cb74972aa5b9fe55fe35d7f45dJosh Gargus 1484e05a29c9b05c8cb74972aa5b9fe55fe35d7f45dJosh Gargus @Override 1494e05a29c9b05c8cb74972aa5b9fe55fe35d7f45dJosh Gargus public void onCallNumberDirectly(String phoneNumber) { 1504e05a29c9b05c8cb74972aa5b9fe55fe35d7f45dJosh Gargus if (mListener != null) { 1514e05a29c9b05c8cb74972aa5b9fe55fe35d7f45dJosh Gargus mListener.onCallNumberDirectly(phoneNumber); 1524e05a29c9b05c8cb74972aa5b9fe55fe35d7f45dJosh Gargus } 1534e05a29c9b05c8cb74972aa5b9fe55fe35d7f45dJosh Gargus } 1549b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1559b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1569b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private class FilterHeaderClickListener implements OnClickListener { 1579b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1589b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onClick(View view) { 15934b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa AccountFilterUtil.startAccountFilterActivityForResult( 160b6553457d0c3e84eefa0a853090b680090a7b2f9Josh Gargus PhoneFavoriteFragment.this, 161b6553457d0c3e84eefa0a853090b680090a7b2f9Josh Gargus REQUEST_CODE_ACCOUNT_FILTER, 162b6553457d0c3e84eefa0a853090b680090a7b2f9Josh Gargus mFilter); 1639b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1649b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1659b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1669b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private class ContactsPreferenceChangeListener 1679b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa implements ContactsPreferences.ChangeListener { 1689b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1699b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onChange() { 1709b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (loadContactsPreferences()) { 1719b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa requestReloadAllContacts(); 1729b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1739b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1749b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1759b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1761dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa private class ScrollListener implements ListView.OnScrollListener { 1771dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa private boolean mShouldShowFastScroller; 1781dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa @Override 1791dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa public void onScroll(AbsListView view, 1801dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa int firstVisibleItem, int visibleItemCount, int totalItemCount) { 1811dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa // FastScroller should be visible only when the user is seeing "all" contacts section. 1821dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa final boolean shouldShow = mAdapter.shouldShowFirstScroller(firstVisibleItem); 1831dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa if (shouldShow != mShouldShowFastScroller) { 184532db253b803d98bfbbc457c5b559834cdb3b326Daisuke Miyakawa mListView.setVerticalScrollBarEnabled(shouldShow); 1851dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mListView.setFastScrollEnabled(shouldShow); 1861dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mListView.setFastScrollAlwaysVisible(shouldShow); 1871dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mShouldShowFastScroller = shouldShow; 1881dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa } 1891dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa } 1901dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa 1911dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa @Override 1921dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa public void onScrollStateChanged(AbsListView view, int scrollState) { 1931dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa } 1941dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa } 1951dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa 1969b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private Listener mListener; 1979b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private PhoneFavoriteMergedAdapter mAdapter; 1989b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private ContactTileAdapter mContactTileAdapter; 1999b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private PhoneNumberListAdapter mAllContactsAdapter; 2009b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2019b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 2029b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * true when the loader for {@link PhoneNumberListAdapter} has started already. 2039b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 2049b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private boolean mAllContactsLoaderStarted; 2059b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 2069b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * true when the loader for {@link PhoneNumberListAdapter} must reload "all" contacts again. 2079b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * It typically happens when {@link ContactsPreferences} has changed its settings 2089b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * (display order and sort order) 2099b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 2109b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private boolean mAllContactsForceReload; 2119b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2129b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private ContactsPreferences mContactsPrefs; 2139b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private ContactListFilter mFilter; 2149b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2159b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private TextView mEmptyView; 2169b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private ListView mListView; 21734b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa /** 21834b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa * Layout containing {@link #mAccountFilterHeader}. Used to limit area being "pressed". 21934b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa */ 22034b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa private FrameLayout mAccountFilterHeaderContainer; 22134b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa private View mAccountFilterHeader; 2229b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2234e05a29c9b05c8cb74972aa5b9fe55fe35d7f45dJosh Gargus private final ContactTileView.Listener mContactTileAdapterListener = 2249b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa new ContactTileAdapterListener(); 2259b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private final LoaderManager.LoaderCallbacks<Cursor> mContactTileLoaderListener = 2269b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa new ContactTileLoaderListener(); 2279b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private final LoaderManager.LoaderCallbacks<Cursor> mAllContactsLoaderListener = 2289b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa new AllContactsLoaderListener(); 2299b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private final OnClickListener mFilterHeaderClickListener = new FilterHeaderClickListener(); 2309b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private final ContactsPreferenceChangeListener mContactsPreferenceChangeListener = 2319b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa new ContactsPreferenceChangeListener(); 2321dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa private final ScrollListener mScrollListener = new ScrollListener(); 2339b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2349b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 2359b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onCreate(Bundle savedState) { 2369b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa super.onCreate(savedState); 2379b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (savedState != null) { 2389b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mFilter = savedState.getParcelable(KEY_FILTER); 2399b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 2407c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa setHasOptionsMenu(true); 2419b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 2429b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2439b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 2449b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onSaveInstanceState(Bundle outState) { 2459b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa super.onSaveInstanceState(outState); 2469b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa outState.putParcelable(KEY_FILTER, mFilter); 2479b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 2489b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2499b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 2509b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onAttach(Activity activity) { 2519b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa super.onAttach(activity); 2529b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2539b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactsPrefs = new ContactsPreferences(activity); 2545db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa } 2559b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2565db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa @Override 2575db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa public View onCreateView(LayoutInflater inflater, ViewGroup container, 2585db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa Bundle savedInstanceState) { 2595db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa final View listLayout = inflater.inflate(R.layout.contact_tile_list, container, false); 2605db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 2615db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView = (ListView) listLayout.findViewById(R.id.contact_tile_list); 2625db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setItemsCanFocus(true); 2635db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setOnItemClickListener(this); 264532db253b803d98bfbbc457c5b559834cdb3b326Daisuke Miyakawa mListView.setVerticalScrollBarEnabled(false); 2655db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT); 2665db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY); 2679b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2685db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa initAdapters(getActivity(), inflater); 2695db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 2705db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setAdapter(mAdapter); 2715db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 2721dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mListView.setOnScrollListener(mScrollListener); 2731dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mListView.setFastScrollEnabled(false); 2741dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mListView.setFastScrollAlwaysVisible(false); 2751dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa 2765db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mEmptyView = (TextView) listLayout.findViewById(R.id.contact_tile_list_empty); 2775db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mEmptyView.setText(getString(R.string.listTotalAllContactsZero)); 2785db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setEmptyView(mEmptyView); 2799b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2809b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa updateFilterHeaderView(); 2815db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 2825db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa return listLayout; 2839b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 2849b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2859b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 2869b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * Constructs and initializes {@link #mContactTileAdapter}, {@link #mAllContactsAdapter}, and 2879b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * {@link #mAllContactsAdapter}. 2885db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * 2895db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * TODO: Move all the code here to {@link PhoneFavoriteMergedAdapter} if possible. 2905db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * There are two problems: account header (whose content changes depending on filter settings) 2915db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * and OnClickListener (which initiates {@link Activity#startActivityForResult(Intent, int)}). 2925db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * See also issue 5429203, 5269692, and 5432286. If we are able to have a singleton for filter, 2935db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * this work will become easier. 2949b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 2955db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa private void initAdapters(Context context, LayoutInflater inflater) { 2969b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactTileAdapter = new ContactTileAdapter(context, mContactTileAdapterListener, 2979b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa getResources().getInteger(R.integer.contact_tile_column_count), 2989b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa ContactTileAdapter.DisplayType.STREQUENT_PHONE_ONLY); 2999b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(context)); 3009b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3019b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Setup the "all" adapter manually. See also the setup logic in ContactEntryListFragment. 3029b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter = new PhoneNumberListAdapter(context); 3039b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setDisplayPhotos(true); 3049b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setQuickContactEnabled(true); 3059b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setSearchMode(false); 3069b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setIncludeProfile(false); 3079b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setSelectionVisible(false); 3089b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setDarkTheme(true); 3099b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setPhotoLoader(ContactPhotoManager.getInstance(context)); 3109b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Disable directory header. 3119b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setHasHeader(0, false); 3129b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Show A-Z section index. 3139b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setSectionHeaderDisplayEnabled(true); 3149b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Disable pinned header. It doesn't work with this fragment. 3159b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setPinnedPartitionHeadersEnabled(false); 3169b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Put photos on left for consistency with "frequent" contacts section. 3179b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT); 3189b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 319e1c007eeb40a40b21e60bb4c8a42e0affd9fcdd1Daisuke Miyakawa mAllContactsAdapter.setUseCallableUri(true); 320e1c007eeb40a40b21e60bb4c8a42e0affd9fcdd1Daisuke Miyakawa 3215db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa if (mFilter != null) { 3225db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mAllContactsAdapter.setFilter(mFilter); 3235db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa } 3245db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 3255db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa // Create the account filter header but keep it hidden until "all" contacts are loaded. 32634b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa mAccountFilterHeaderContainer = new FrameLayout(context, null); 327b5c0b93e37e2b471ea46a1889e2eb194292284b7Daisuke Miyakawa mAccountFilterHeader = inflater.inflate(R.layout.account_filter_header_for_phone_favorite, 328b5c0b93e37e2b471ea46a1889e2eb194292284b7Daisuke Miyakawa mListView, false); 32934b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener); 33034b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa mAccountFilterHeaderContainer.addView(mAccountFilterHeader); 3315db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mAccountFilterHeaderContainer.setVisibility(View.GONE); 3325db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 3335db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mAdapter = new PhoneFavoriteMergedAdapter(context, 3345db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter); 3355db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 3369b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 3379b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3389b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 3397c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 3407c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa super.onCreateOptionsMenu(menu, inflater); 341091034c2d4c3ea69fc63c2e9d0956a109a13e08eDaisuke Miyakawa inflater.inflate(R.menu.phone_favorite_options, menu); 3427c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa } 3437c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa 3447c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa @Override 3457c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa public boolean onOptionsItemSelected(MenuItem item) { 3467c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa switch (item.getItemId()) { 3477c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa case R.id.menu_import_export: 348e05f8efc11a383b8299e3a16b79a5d27531251d4Josh Gargus // We hard-code the "contactsAreAvailable" argument because doing it properly would 349e05f8efc11a383b8299e3a16b79a5d27531251d4Josh Gargus // involve querying a {@link ProviderStatusLoader}, which we don't want to do right 350091034c2d4c3ea69fc63c2e9d0956a109a13e08eDaisuke Miyakawa // now in Dialtacts for (potential) performance reasons. Compare with how it is 351e05f8efc11a383b8299e3a16b79a5d27531251d4Josh Gargus // done in {@link PeopleActivity}. 352e05f8efc11a383b8299e3a16b79a5d27531251d4Josh Gargus ImportExportDialogFragment.show(getFragmentManager(), true); 3537c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa return true; 3547c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa case R.id.menu_accounts: 3557c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS); 3567c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] { 3577c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa ContactsContract.AUTHORITY 3587c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa }); 3597c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 3607c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa startActivity(intent); 3617c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa return true; 3627c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa } 3637c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa return false; 3647c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa } 3657c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa 3667c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa @Override 3679b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onStart() { 3689b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa super.onStart(); 3699b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3709b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactsPrefs.registerChangeListener(mContactsPreferenceChangeListener); 3719b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3729b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // If ContactsPreferences has changed, we need to reload "all" contacts with the new 3739b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // settings. If mAllContactsFoarceReload is already true, it should be kept. 3749b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (loadContactsPreferences()) { 3759b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsForceReload = true; 3769b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 3779b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3789b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Use initLoader() instead of reloadLoader() to refraing unnecessary reload. 3799b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // This method call implicitly assures ContactTileLoaderListener's onLoadFinished() will 3809b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // be called, on which we'll check if "all" contacts should be reloaded again or not. 3819b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null, mContactTileLoaderListener); 3829b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 3839b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3849b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 3859b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onStop() { 3869b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa super.onStop(); 3879b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactsPrefs.unregisterChangeListener(); 3889b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 3899b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3909b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 3919b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * {@inheritDoc} 3929b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * 3939b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * This is only effective for elements provided by {@link #mContactTileAdapter}. 3949b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * {@link #mContactTileAdapter} has its own logic for click events. 3959b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 3969b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 3979b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 3989b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa final int contactTileAdapterCount = mContactTileAdapter.getCount(); 3999b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (position <= contactTileAdapterCount) { 4009b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa Log.e(TAG, "onItemClick() event for unexpected position. " 4019b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa + "The position " + position + " is before \"all\" section. Ignored."); 4029b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } else { 4039b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa final int localPosition = position - mContactTileAdapter.getCount() - 1; 4049b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mListener != null) { 4059b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mListener.onContactSelected(mAllContactsAdapter.getDataUri(localPosition)); 4069b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4079b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4089b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4099b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 41034b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa @Override 41134b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa public void onActivityResult(int requestCode, int resultCode, Intent data) { 41234b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa if (requestCode == REQUEST_CODE_ACCOUNT_FILTER) { 41334b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa if (getActivity() != null) { 41434b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa AccountFilterUtil.handleAccountFilterResult( 41534b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa ContactListFilterController.getInstance(getActivity()), resultCode, data); 41634b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa } else { 41734b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa Log.e(TAG, "getActivity() returns null during Fragment#onActivityResult()"); 41834b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa } 41934b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa } 42034b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa } 42134b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa 4229b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private boolean loadContactsPreferences() { 4239b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mContactsPrefs == null || mAllContactsAdapter == null) { 4249b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return false; 4259b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4269b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4279b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa boolean changed = false; 4289b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mAllContactsAdapter.getContactNameDisplayOrder() != mContactsPrefs.getDisplayOrder()) { 4299b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder()); 4309b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa changed = true; 4319b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4329b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4339b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mAllContactsAdapter.getSortOrder() != mContactsPrefs.getSortOrder()) { 4349b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setSortOrder(mContactsPrefs.getSortOrder()); 4359b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa changed = true; 4369b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4379b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4389b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return changed; 4399b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4409b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4419b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 4429b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * Requests to reload "all" contacts. If the section is already loaded, this method will 4439b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * force reloading it now. If the section isn't loaded yet, the actual load may be done later 4449b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * (on {@link #onStart()}. 4459b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 4469b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private void requestReloadAllContacts() { 4479b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) { 4489b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa Log.d(TAG, "requestReloadAllContacts()" 4499b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa + " mAllContactsAdapter: " + mAllContactsAdapter 4509b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa + ", mAllContactsLoaderStarted: " + mAllContactsLoaderStarted); 4519b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4529b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4539b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mAllContactsAdapter == null || !mAllContactsLoaderStarted) { 4549b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Remember this request until next load on onStart(). 4559b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsForceReload = true; 4569b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return; 4579b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4589b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4599b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "Reload \"all\" contacts now."); 4609b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4619b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.onDataReload(); 4629b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Use restartLoader() to make LoaderManager to load the section again. 4639b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa getLoaderManager().restartLoader(LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener); 4649b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4659b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4669b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private void updateFilterHeaderView() { 4679b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa final ContactListFilter filter = getFilter(); 46834b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa if (mAccountFilterHeader == null || mAllContactsAdapter == null || filter == null) { 46934b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa return; 4709b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 47134b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa AccountFilterUtil.updateAccountFilterTitleForPhone( 47234b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa mAccountFilterHeader, filter, mAllContactsAdapter.isLoading(), true); 4739b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4749b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4759b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public ContactListFilter getFilter() { 4769b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return mFilter; 4779b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4789b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4799b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void setFilter(ContactListFilter filter) { 4809b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if ((mFilter == null && filter == null) || (mFilter != null && mFilter.equals(filter))) { 4819b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return; 4829b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4839b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4849b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) { 4859b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa Log.d(TAG, "setFilter(). old filter (" + mFilter 4869b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa + ") will be replaced with new filter (" + filter + ")"); 4879b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4889b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4899b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mFilter = filter; 4909b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4915db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa if (mAllContactsAdapter != null) { 4925db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mAllContactsAdapter.setFilter(mFilter); 4935db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa requestReloadAllContacts(); 4945db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa updateFilterHeaderView(); 4955db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa } 4969b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4979b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4989b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void setListener(Listener listener) { 4999b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mListener = listener; 5009b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 501aabc1e81c2d43827fe2ad0bdde6851bdfb431924Josh Gargus} 502