PhoneFavoriteFragment.java revision b6553457d0c3e84eefa0a853090b680090a7b2f9
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); 789b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 799b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 809b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> { 819b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 829b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public CursorLoader onCreateLoader(int id, Bundle args) { 839b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onCreateLoader."); 849b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return ContactTileLoaderFactory.createStrequentPhoneOnlyLoader(getActivity()); 859b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 869b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 879b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 889b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 899b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoadFinished"); 909b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactTileAdapter.setContactCursor(data); 919b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 929b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mAllContactsForceReload) { 939b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.onDataReload(); 949b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Use restartLoader() to make LoaderManager to load the section again. 959b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa getLoaderManager().restartLoader( 969b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener); 979b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } else if (!mAllContactsLoaderStarted) { 989b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Load "all" contacts if not loaded yet. 999b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa getLoaderManager().initLoader( 1009b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener); 1019b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1029b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsForceReload = false; 1039b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsLoaderStarted = true; 1049b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1059b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Show the filter header with "loading" state. 1069b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa updateFilterHeaderView(); 10734b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa mAccountFilterHeader.setVisibility(View.VISIBLE); 1089b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1099b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1109b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1119b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onLoaderReset(Loader<Cursor> loader) { 1129b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoaderReset. "); 1139b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1149b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1159b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1169b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private class AllContactsLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> { 1179b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1189b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public Loader<Cursor> onCreateLoader(int id, Bundle args) { 1199b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onCreateLoader"); 1209b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa CursorLoader loader = new CursorLoader(getActivity(), null, null, null, null, null); 1219b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.configureLoader(loader, Directory.DEFAULT); 1229b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return loader; 1239b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1249b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1259b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1269b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 1279b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onLoadFinished"); 1289b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.changeCursor(0, data); 1299b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa updateFilterHeaderView(); 1309b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAccountFilterHeaderContainer.setVisibility(View.VISIBLE); 1319b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1329b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1339b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1349b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onLoaderReset(Loader<Cursor> loader) { 1359b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onLoaderReset. "); 1369b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1379b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1389b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1399b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private class ContactTileAdapterListener implements ContactTileAdapter.Listener { 1409b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1417a700cf798a19a8452b8671f643a05336f63f611Katherine Kuan public void onContactSelected(Uri contactUri, Rect targetRect) { 1429b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mListener != null) { 1439b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mListener.onContactSelected(contactUri); 1449b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1459b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1469b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1479b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1489b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private class FilterHeaderClickListener implements OnClickListener { 1499b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1509b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onClick(View view) { 15134b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa AccountFilterUtil.startAccountFilterActivityForResult( 152b6553457d0c3e84eefa0a853090b680090a7b2f9Josh Gargus PhoneFavoriteFragment.this, 153b6553457d0c3e84eefa0a853090b680090a7b2f9Josh Gargus REQUEST_CODE_ACCOUNT_FILTER, 154b6553457d0c3e84eefa0a853090b680090a7b2f9Josh Gargus mFilter); 1559b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1569b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1579b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1589b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private class ContactsPreferenceChangeListener 1599b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa implements ContactsPreferences.ChangeListener { 1609b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 1619b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onChange() { 1629b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (loadContactsPreferences()) { 1639b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa requestReloadAllContacts(); 1649b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1659b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1669b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 1679b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1681dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa private class ScrollListener implements ListView.OnScrollListener { 1691dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa private boolean mShouldShowFastScroller; 1701dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa @Override 1711dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa public void onScroll(AbsListView view, 1721dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa int firstVisibleItem, int visibleItemCount, int totalItemCount) { 1731dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa // FastScroller should be visible only when the user is seeing "all" contacts section. 1741dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa final boolean shouldShow = mAdapter.shouldShowFirstScroller(firstVisibleItem); 1751dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa if (shouldShow != mShouldShowFastScroller) { 176532db253b803d98bfbbc457c5b559834cdb3b326Daisuke Miyakawa mListView.setVerticalScrollBarEnabled(shouldShow); 1771dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mListView.setFastScrollEnabled(shouldShow); 1781dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mListView.setFastScrollAlwaysVisible(shouldShow); 1791dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mShouldShowFastScroller = shouldShow; 1801dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa } 1811dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa } 1821dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa 1831dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa @Override 1841dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa public void onScrollStateChanged(AbsListView view, int scrollState) { 1851dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa } 1861dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa } 1871dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa 1889b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private Listener mListener; 1899b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private PhoneFavoriteMergedAdapter mAdapter; 1909b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private ContactTileAdapter mContactTileAdapter; 1919b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private PhoneNumberListAdapter mAllContactsAdapter; 1929b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 1939b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 1949b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * true when the loader for {@link PhoneNumberListAdapter} has started already. 1959b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 1969b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private boolean mAllContactsLoaderStarted; 1979b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 1989b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * true when the loader for {@link PhoneNumberListAdapter} must reload "all" contacts again. 1999b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * It typically happens when {@link ContactsPreferences} has changed its settings 2009b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * (display order and sort order) 2019b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 2029b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private boolean mAllContactsForceReload; 2039b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2049b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private ContactsPreferences mContactsPrefs; 2059b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private ContactListFilter mFilter; 2069b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2079b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private TextView mEmptyView; 2089b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private ListView mListView; 20934b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa /** 21034b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa * Layout containing {@link #mAccountFilterHeader}. Used to limit area being "pressed". 21134b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa */ 21234b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa private FrameLayout mAccountFilterHeaderContainer; 21334b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa private View mAccountFilterHeader; 2149b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2159b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private final ContactTileAdapter.Listener mContactTileAdapterListener = 2169b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa new ContactTileAdapterListener(); 2179b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private final LoaderManager.LoaderCallbacks<Cursor> mContactTileLoaderListener = 2189b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa new ContactTileLoaderListener(); 2199b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private final LoaderManager.LoaderCallbacks<Cursor> mAllContactsLoaderListener = 2209b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa new AllContactsLoaderListener(); 2219b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private final OnClickListener mFilterHeaderClickListener = new FilterHeaderClickListener(); 2229b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private final ContactsPreferenceChangeListener mContactsPreferenceChangeListener = 2239b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa new ContactsPreferenceChangeListener(); 2241dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa private final ScrollListener mScrollListener = new ScrollListener(); 2259b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2269b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 2279b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onCreate(Bundle savedState) { 2289b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa super.onCreate(savedState); 2299b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (savedState != null) { 2309b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mFilter = savedState.getParcelable(KEY_FILTER); 2319b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 2327c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa setHasOptionsMenu(true); 2339b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 2349b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2359b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 2369b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onSaveInstanceState(Bundle outState) { 2379b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa super.onSaveInstanceState(outState); 2389b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa outState.putParcelable(KEY_FILTER, mFilter); 2399b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 2409b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2419b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 2429b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onAttach(Activity activity) { 2439b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa super.onAttach(activity); 2449b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2459b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactsPrefs = new ContactsPreferences(activity); 2465db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa } 2479b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2485db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa @Override 2495db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa public View onCreateView(LayoutInflater inflater, ViewGroup container, 2505db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa Bundle savedInstanceState) { 2515db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa final View listLayout = inflater.inflate(R.layout.contact_tile_list, container, false); 2525db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 2535db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView = (ListView) listLayout.findViewById(R.id.contact_tile_list); 2545db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setItemsCanFocus(true); 2555db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setOnItemClickListener(this); 256532db253b803d98bfbbc457c5b559834cdb3b326Daisuke Miyakawa mListView.setVerticalScrollBarEnabled(false); 2575db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT); 2585db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY); 2599b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2605db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa initAdapters(getActivity(), inflater); 2615db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 2625db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setAdapter(mAdapter); 2635db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 2641dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mListView.setOnScrollListener(mScrollListener); 2651dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mListView.setFastScrollEnabled(false); 2661dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa mListView.setFastScrollAlwaysVisible(false); 2671dff6b60c28fa34e477b84c95c4bbe6c9b482416Daisuke Miyakawa 2685db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mEmptyView = (TextView) listLayout.findViewById(R.id.contact_tile_list_empty); 2695db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mEmptyView.setText(getString(R.string.listTotalAllContactsZero)); 2705db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mListView.setEmptyView(mEmptyView); 2719b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2729b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa updateFilterHeaderView(); 2735db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 2745db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa return listLayout; 2759b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 2769b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2779b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 2789b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * Constructs and initializes {@link #mContactTileAdapter}, {@link #mAllContactsAdapter}, and 2799b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * {@link #mAllContactsAdapter}. 2805db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * 2815db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * TODO: Move all the code here to {@link PhoneFavoriteMergedAdapter} if possible. 2825db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * There are two problems: account header (whose content changes depending on filter settings) 2835db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * and OnClickListener (which initiates {@link Activity#startActivityForResult(Intent, int)}). 2845db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * See also issue 5429203, 5269692, and 5432286. If we are able to have a singleton for filter, 2855db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa * this work will become easier. 2869b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 2875db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa private void initAdapters(Context context, LayoutInflater inflater) { 2889b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactTileAdapter = new ContactTileAdapter(context, mContactTileAdapterListener, 2899b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa getResources().getInteger(R.integer.contact_tile_column_count), 2909b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa ContactTileAdapter.DisplayType.STREQUENT_PHONE_ONLY); 2919b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(context)); 2929b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 2939b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Setup the "all" adapter manually. See also the setup logic in ContactEntryListFragment. 2949b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter = new PhoneNumberListAdapter(context); 2959b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setDisplayPhotos(true); 2969b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setQuickContactEnabled(true); 2979b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setSearchMode(false); 2989b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setIncludeProfile(false); 2999b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setSelectionVisible(false); 3009b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setDarkTheme(true); 3019b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setPhotoLoader(ContactPhotoManager.getInstance(context)); 3029b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Disable directory header. 3039b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setHasHeader(0, false); 3049b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Show A-Z section index. 3059b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setSectionHeaderDisplayEnabled(true); 3069b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Disable pinned header. It doesn't work with this fragment. 3079b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setPinnedPartitionHeadersEnabled(false); 3089b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Put photos on left for consistency with "frequent" contacts section. 3099b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT); 3109b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 311e1c007eeb40a40b21e60bb4c8a42e0affd9fcdd1Daisuke Miyakawa mAllContactsAdapter.setUseCallableUri(true); 312e1c007eeb40a40b21e60bb4c8a42e0affd9fcdd1Daisuke Miyakawa 3135db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa if (mFilter != null) { 3145db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mAllContactsAdapter.setFilter(mFilter); 3155db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa } 3165db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 3175db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa // Create the account filter header but keep it hidden until "all" contacts are loaded. 31834b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa mAccountFilterHeaderContainer = new FrameLayout(context, null); 319b5c0b93e37e2b471ea46a1889e2eb194292284b7Daisuke Miyakawa mAccountFilterHeader = inflater.inflate(R.layout.account_filter_header_for_phone_favorite, 320b5c0b93e37e2b471ea46a1889e2eb194292284b7Daisuke Miyakawa mListView, false); 32134b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener); 32234b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa mAccountFilterHeaderContainer.addView(mAccountFilterHeader); 3235db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mAccountFilterHeaderContainer.setVisibility(View.GONE); 3245db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 3255db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mAdapter = new PhoneFavoriteMergedAdapter(context, 3265db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter); 3275db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa 3289b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 3299b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3309b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 3317c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 3327c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa super.onCreateOptionsMenu(menu, inflater); 333091034c2d4c3ea69fc63c2e9d0956a109a13e08eDaisuke Miyakawa inflater.inflate(R.menu.phone_favorite_options, menu); 3347c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa } 3357c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa 3367c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa @Override 3377c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa public boolean onOptionsItemSelected(MenuItem item) { 3387c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa switch (item.getItemId()) { 3397c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa case R.id.menu_import_export: 340e05f8efc11a383b8299e3a16b79a5d27531251d4Josh Gargus // We hard-code the "contactsAreAvailable" argument because doing it properly would 341e05f8efc11a383b8299e3a16b79a5d27531251d4Josh Gargus // involve querying a {@link ProviderStatusLoader}, which we don't want to do right 342091034c2d4c3ea69fc63c2e9d0956a109a13e08eDaisuke Miyakawa // now in Dialtacts for (potential) performance reasons. Compare with how it is 343e05f8efc11a383b8299e3a16b79a5d27531251d4Josh Gargus // done in {@link PeopleActivity}. 344e05f8efc11a383b8299e3a16b79a5d27531251d4Josh Gargus ImportExportDialogFragment.show(getFragmentManager(), true); 3457c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa return true; 3467c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa case R.id.menu_accounts: 3477c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS); 3487c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] { 3497c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa ContactsContract.AUTHORITY 3507c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa }); 3517c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 3527c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa startActivity(intent); 3537c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa return true; 3547c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa } 3557c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa return false; 3567c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa } 3577c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa 3587c30236364c71618da4b266a61a77e9711aa23f1Daisuke Miyakawa @Override 3599b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onStart() { 3609b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa super.onStart(); 3619b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3629b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactsPrefs.registerChangeListener(mContactsPreferenceChangeListener); 3639b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3649b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // If ContactsPreferences has changed, we need to reload "all" contacts with the new 3659b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // settings. If mAllContactsFoarceReload is already true, it should be kept. 3669b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (loadContactsPreferences()) { 3679b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsForceReload = true; 3689b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 3699b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3709b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Use initLoader() instead of reloadLoader() to refraing unnecessary reload. 3719b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // This method call implicitly assures ContactTileLoaderListener's onLoadFinished() will 3729b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // be called, on which we'll check if "all" contacts should be reloaded again or not. 3739b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null, mContactTileLoaderListener); 3749b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 3759b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3769b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 3779b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onStop() { 3789b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa super.onStop(); 3799b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mContactsPrefs.unregisterChangeListener(); 3809b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 3819b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 3829b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 3839b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * {@inheritDoc} 3849b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * 3859b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * This is only effective for elements provided by {@link #mContactTileAdapter}. 3869b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * {@link #mContactTileAdapter} has its own logic for click events. 3879b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 3889b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa @Override 3899b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 3909b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa final int contactTileAdapterCount = mContactTileAdapter.getCount(); 3919b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (position <= contactTileAdapterCount) { 3929b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa Log.e(TAG, "onItemClick() event for unexpected position. " 3939b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa + "The position " + position + " is before \"all\" section. Ignored."); 3949b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } else { 3959b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa final int localPosition = position - mContactTileAdapter.getCount() - 1; 3969b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mListener != null) { 3979b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mListener.onContactSelected(mAllContactsAdapter.getDataUri(localPosition)); 3989b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 3999b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4009b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4019b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 40234b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa @Override 40334b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa public void onActivityResult(int requestCode, int resultCode, Intent data) { 40434b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa if (requestCode == REQUEST_CODE_ACCOUNT_FILTER) { 40534b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa if (getActivity() != null) { 40634b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa AccountFilterUtil.handleAccountFilterResult( 40734b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa ContactListFilterController.getInstance(getActivity()), resultCode, data); 40834b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa } else { 40934b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa Log.e(TAG, "getActivity() returns null during Fragment#onActivityResult()"); 41034b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa } 41134b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa } 41234b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa } 41334b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa 4149b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private boolean loadContactsPreferences() { 4159b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mContactsPrefs == null || mAllContactsAdapter == null) { 4169b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return false; 4179b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4189b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4199b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa boolean changed = false; 4209b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mAllContactsAdapter.getContactNameDisplayOrder() != mContactsPrefs.getDisplayOrder()) { 4219b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder()); 4229b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa changed = true; 4239b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4249b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4259b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mAllContactsAdapter.getSortOrder() != mContactsPrefs.getSortOrder()) { 4269b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.setSortOrder(mContactsPrefs.getSortOrder()); 4279b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa changed = true; 4289b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4299b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4309b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return changed; 4319b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4329b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4339b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa /** 4349b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * Requests to reload "all" contacts. If the section is already loaded, this method will 4359b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * force reloading it now. If the section isn't loaded yet, the actual load may be done later 4369b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa * (on {@link #onStart()}. 4379b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa */ 4389b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private void requestReloadAllContacts() { 4399b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) { 4409b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa Log.d(TAG, "requestReloadAllContacts()" 4419b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa + " mAllContactsAdapter: " + mAllContactsAdapter 4429b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa + ", mAllContactsLoaderStarted: " + mAllContactsLoaderStarted); 4439b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4449b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4459b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (mAllContactsAdapter == null || !mAllContactsLoaderStarted) { 4469b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Remember this request until next load on onStart(). 4479b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsForceReload = true; 4489b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return; 4499b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4509b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4519b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) Log.d(TAG, "Reload \"all\" contacts now."); 4529b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4539b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mAllContactsAdapter.onDataReload(); 4549b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa // Use restartLoader() to make LoaderManager to load the section again. 4559b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa getLoaderManager().restartLoader(LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener); 4569b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4579b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4589b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa private void updateFilterHeaderView() { 4599b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa final ContactListFilter filter = getFilter(); 46034b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa if (mAccountFilterHeader == null || mAllContactsAdapter == null || filter == null) { 46134b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa return; 4629b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 46334b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa AccountFilterUtil.updateAccountFilterTitleForPhone( 46434b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa mAccountFilterHeader, filter, mAllContactsAdapter.isLoading(), true); 4659b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4669b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4679b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public ContactListFilter getFilter() { 4689b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return mFilter; 4699b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4709b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4719b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void setFilter(ContactListFilter filter) { 4729b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if ((mFilter == null && filter == null) || (mFilter != null && mFilter.equals(filter))) { 4739b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa return; 4749b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4759b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4769b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa if (DEBUG) { 4779b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa Log.d(TAG, "setFilter(). old filter (" + mFilter 4789b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa + ") will be replaced with new filter (" + filter + ")"); 4799b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4809b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4819b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mFilter = filter; 4829b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4835db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa if (mAllContactsAdapter != null) { 4845db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa mAllContactsAdapter.setFilter(mFilter); 4855db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa requestReloadAllContacts(); 4865db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa updateFilterHeaderView(); 4875db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa } 4889b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4899b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa 4909b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa public void setListener(Listener listener) { 4919b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa mListener = listener; 4929b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa } 4939b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa}