16b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee/* 2dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee * Copyright (C) 2013 The Android Open Source Project 36b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * 46b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * Licensed under the Apache License, Version 2.0 (the "License"); 56b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * you may not use this file except in compliance with the License. 66b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * You may obtain a copy of the License at 76b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * 86b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * http://www.apache.org/licenses/LICENSE-2.0 96b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * 106b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * Unless required by applicable law or agreed to in writing, software 116b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * distributed under the License is distributed on an "AS IS" BASIS, 126b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * See the License for the specific language governing permissions and 146b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * limitations under the License. 156b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee */ 166b049128c51b90e17ae14856d98130a22d3a5433Yorke Leepackage com.android.dialer.list; 176b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 185b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wangimport android.animation.Animator; 195b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wangimport android.animation.AnimatorSet; 204fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chenimport android.animation.ArgbEvaluator; 215b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wangimport android.animation.ObjectAnimator; 224fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chenimport android.animation.ValueAnimator; 236b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.app.Activity; 246b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.app.Fragment; 256b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.app.LoaderManager; 2621299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Leeimport android.content.Context; 276b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.content.CursorLoader; 286b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.content.Loader; 2921299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Leeimport android.content.SharedPreferences; 30fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Leeimport android.content.res.Resources; 316b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.database.Cursor; 326b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.graphics.Rect; 336b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.net.Uri; 346b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.os.Bundle; 35c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Chengimport android.provider.CallLog; 366b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.util.Log; 376b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.view.LayoutInflater; 386b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.view.View; 39c36684277aa45085999284bfe71cb8be71b3a464Yorke Leeimport android.view.ViewTreeObserver; 406b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.view.View.OnClickListener; 416b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.view.ViewGroup; 426b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.widget.AbsListView; 436b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.widget.AdapterView; 446b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.widget.AdapterView.OnItemClickListener; 454911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wangimport android.widget.ImageView; 466b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.widget.ListView; 473eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Leeimport android.widget.RelativeLayout; 483eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Leeimport android.widget.RelativeLayout.LayoutParams; 496b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 506b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport com.android.contacts.common.ContactPhotoManager; 516b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport com.android.contacts.common.ContactTileLoaderFactory; 52dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Leeimport com.android.contacts.common.GeoUtil; 53c36684277aa45085999284bfe71cb8be71b3a464Yorke Leeimport com.android.contacts.common.list.ContactEntry; 54fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Leeimport com.android.contacts.common.list.ContactListItemView; 556b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport com.android.contacts.common.list.ContactTileView; 5621299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Leeimport com.android.dialer.DialtactsActivity; 576b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport com.android.dialer.R; 5821299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Leeimport com.android.dialer.calllog.CallLogQuery; 59dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Leeimport com.android.dialer.calllog.ContactInfoHelper; 60fb585079cc4c522c27f6dd6bf03fd296535960f3Yorke Leeimport com.android.dialer.calllog.CallLogAdapter; 61dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Leeimport com.android.dialer.calllog.CallLogQueryHandler; 62c36684277aa45085999284bfe71cb8be71b3a464Yorke Leeimport com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow; 63704acc087ce359295475a46695c2821c55778344Chiao Chengimport com.android.dialerbind.ObjectFactory; 64c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 65c36684277aa45085999284bfe71cb8be71b3a464Yorke Leeimport java.util.ArrayList; 66c36684277aa45085999284bfe71cb8be71b3a464Yorke Leeimport java.util.HashMap; 676b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 686b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee/** 696b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * Fragment for Phone UI's favorite screen. 706b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * 716b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * This fragment contains three kinds of contacts in one screen: "starred", "frequent", and "all" 726b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * contacts. To show them at once, this merges results from {@link com.android.contacts.common.list.ContactTileAdapter} and 736b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * {@link com.android.contacts.common.list.PhoneNumberListAdapter} into one unified list using {@link PhoneFavoriteMergedAdapter}. 746b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * A contact filter header is also inserted between those adapters' results. 756b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee */ 768898cd0577d41cfa4e6acf785c9e904bd71fbdfdYorke Leepublic class PhoneFavoriteFragment extends Fragment implements OnItemClickListener, 77c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher, 78c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee PhoneFavoritesTileAdapter.OnDataSetChangedForAnimationListener { 79c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 804ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee /** 814ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee * By default, the animation code assumes that all items in a list view are of the same height 824ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee * when animating new list items into view (e.g. from the bottom of the screen into view). 834ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee * This can cause incorrect translation offsets when a item that is larger or smaller than 844ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee * other list item is removed from the list. This key is used to provide the actual height 854ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee * of the removed object so that the actual translation appears correct to the user. 864ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee */ 874ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee private static final long KEY_REMOVED_ITEM_HEIGHT = Long.MAX_VALUE; 884ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee 898898cd0577d41cfa4e6acf785c9e904bd71fbdfdYorke Lee private static final String TAG = PhoneFavoriteFragment.class.getSimpleName(); 903ed80a357d780310777178ad589d7771d4f7bf2dYorke Lee private static final boolean DEBUG = false; 91c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 924911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang private int mAnimationDuration; 936b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 946b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee /** 956b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * Used with LoaderManager. 966b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee */ 976b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee private static int LOADER_ID_CONTACT_TILE = 1; 98c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng private static int MISSED_CALL_LOADER = 2; 996b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 10021299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee private static final String KEY_LAST_DISMISSED_CALL_SHORTCUT_DATE = 10121299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee "key_last_dismissed_call_shortcut_date"; 10221299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee 1038dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee public interface OnShowAllContactsListener { 1048dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee public void onShowAllContacts(); 1058dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee } 1068dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee 1076b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public interface Listener { 1086b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onContactSelected(Uri contactUri); 1096b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onCallNumberDirectly(String phoneNumber); 1106b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1116b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 112c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng private class MissedCallLogLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> { 113c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng 114c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng @Override 115c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng public Loader<Cursor> onCreateLoader(int id, Bundle args) { 116c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng final Uri uri = CallLog.Calls.CONTENT_URI; 117c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng final String[] projection = new String[] {CallLog.Calls.TYPE}; 118c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng final String selection = CallLog.Calls.TYPE + " = " + CallLog.Calls.MISSED_TYPE + 119c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng " AND " + CallLog.Calls.IS_READ + " = 0"; 120c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng return new CursorLoader(getActivity(), uri, projection, selection, null, null); 121c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng } 122c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng 123c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng @Override 124c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor data) { 125c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng mCallLogAdapter.setMissedCalls(data); 126c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng } 127c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng 128c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng @Override 129c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng public void onLoaderReset(Loader<Cursor> cursorLoader) { 130c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng } 131c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng } 132c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng 1336b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee private class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> { 1346b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 1356b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public CursorLoader onCreateLoader(int id, Bundle args) { 1366b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onCreateLoader."); 1376b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee return ContactTileLoaderFactory.createStrequentPhoneOnlyLoader(getActivity()); 1386b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1396b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 1406b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 1416b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 1426b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoadFinished"); 1436b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mContactTileAdapter.setContactCursor(data); 1444fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen setEmptyViewVisibility(mContactTileAdapter.getCount() == 0); 1456b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1466b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 1476b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 1486b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onLoaderReset(Loader<Cursor> loader) { 1496b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoaderReset. "); 1506b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1516b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1526b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 1536b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee private class ContactTileAdapterListener implements ContactTileView.Listener { 1546b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 1556b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onContactSelected(Uri contactUri, Rect targetRect) { 1566b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee if (mListener != null) { 1576b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListener.onContactSelected(contactUri); 1586b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1596b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1606b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 1616b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 1626b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onCallNumberDirectly(String phoneNumber) { 1636b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee if (mListener != null) { 1646b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListener.onCallNumberDirectly(phoneNumber); 1656b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1666b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1676b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 1686b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 1696b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public int getApproximateTileWidth() { 1706b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee return getView().getWidth() / mContactTileAdapter.getColumnCount(); 1716b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1726b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1736b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 1746b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee private class ScrollListener implements ListView.OnScrollListener { 1756b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 1766b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onScroll(AbsListView view, 1776b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee int firstVisibleItem, int visibleItemCount, int totalItemCount) { 1786b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1796b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 1806b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 1816b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onScrollStateChanged(AbsListView view, int scrollState) { 182dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee mActivityScrollListener.onListFragmentScrollStateChange(scrollState); 1836b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1846b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 1856b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 1866b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee private Listener mListener; 187dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee 188dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee private OnListFragmentScrolledListener mActivityScrollListener; 1898dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee private OnShowAllContactsListener mShowAllContactsListener; 1908898cd0577d41cfa4e6acf785c9e904bd71fbdfdYorke Lee private PhoneFavoriteMergedAdapter mAdapter; 191dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee private PhoneFavoritesTileAdapter mContactTileAdapter; 1926b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 193fb585079cc4c522c27f6dd6bf03fd296535960f3Yorke Lee private CallLogAdapter mCallLogAdapter; 194dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee private CallLogQueryHandler mCallLogQueryHandler; 195dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee 1964fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen private View mParentView; 1974fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen 198bf5b298b1a5752a56315131a22434185198370a8Hongwei Wang private PhoneFavoriteListView mListView; 19918e7fdd55f67e3636c161462cb54e7f5555a04deYorke Lee 2006091473941d277ed3746143c1ca9bffdfbe2bd94Christine Chen private View mShowAllContactsButton; 2014fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen private View mShowAllContactsInEmptyViewButton; 2023eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee private View mContactTileFrame; 2036b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 2041f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen private TileInteractionTeaserView mTileInteractionTeaserView; 2051f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen 206c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee private final HashMap<Long, Integer> mItemIdTopMap = new HashMap<Long, Integer>(); 207c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee private final HashMap<Long, Integer> mItemIdLeftMap = new HashMap<Long, Integer>(); 208c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 2096b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee /** 21018e7fdd55f67e3636c161462cb54e7f5555a04deYorke Lee * Layout used when there are no favorites. 2116b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee */ 21218e7fdd55f67e3636c161462cb54e7f5555a04deYorke Lee private View mEmptyView; 2136b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 21421299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee /** 21521299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee * Call shortcuts older than this date (persisted in shared preferences) will not show up in 21621299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee * at the top of the screen 21721299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee */ 21821299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee private long mLastCallShortcutDate = 0; 21921299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee 22021299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee /** 22121299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee * The date of the current call shortcut that is showing on screen. 22221299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee */ 22321299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee private long mCurrentCallShortcutDate = 0; 22421299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee 2256b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee private final ContactTileView.Listener mContactTileAdapterListener = 2266b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee new ContactTileAdapterListener(); 2276b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee private final LoaderManager.LoaderCallbacks<Cursor> mContactTileLoaderListener = 2286b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee new ContactTileLoaderListener(); 2296b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee private final ScrollListener mScrollListener = new ScrollListener(); 2306b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 2316b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 2326b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onAttach(Activity activity) { 2336b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee if (DEBUG) Log.d(TAG, "onAttach()"); 2346b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee super.onAttach(activity); 2356b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 2366b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee // Construct two base adapters which will become part of PhoneFavoriteMergedAdapter. 2376b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee // We don't construct the resultant adapter at this moment since it requires LayoutInflater 2386b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee // that will be available on onCreateView(). 239dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee mContactTileAdapter = new PhoneFavoritesTileAdapter(activity, mContactTileAdapterListener, 240c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee this, 241dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee getResources().getInteger(R.integer.contact_tile_column_count_in_favorites_new), 242dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee 1); 2436b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity)); 2446b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 2456b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 2466b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 2476b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onCreate(Bundle savedState) { 2486b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee if (DEBUG) Log.d(TAG, "onCreate()"); 2496b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee super.onCreate(savedState); 2506b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 2514911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang mAnimationDuration = getResources().getInteger(R.integer.fade_duration); 252dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee mCallLogQueryHandler = new CallLogQueryHandler(getActivity().getContentResolver(), 253dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee this, 1); 254dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee final String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity()); 255704acc087ce359295475a46695c2821c55778344Chiao Cheng mCallLogAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this, 256704acc087ce359295475a46695c2821c55778344Chiao Cheng new ContactInfoHelper(getActivity(), currentCountryIso), true, false); 2576b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee setHasOptionsMenu(true); 2586b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 2596b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 2606b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 261dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee public void onResume() { 262dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee super.onResume(); 26321299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee final SharedPreferences prefs = getActivity().getSharedPreferences( 26421299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee DialtactsActivity.SHARED_PREFS_NAME, Context.MODE_PRIVATE); 26521299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee 26621299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee mLastCallShortcutDate = prefs.getLong(KEY_LAST_DISMISSED_CALL_SHORTCUT_DATE, 0); 26721299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee 2684dc32bdf10bff18acbc1964d289354556950d2ebYorke Lee fetchCalls(); 269dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee mCallLogAdapter.setLoading(true); 27011ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee getLoaderManager().getLoader(LOADER_ID_CONTACT_TILE).forceLoad(); 2716b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 2726b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 2736b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 2746b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public View onCreateView(LayoutInflater inflater, ViewGroup container, 2756b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee Bundle savedInstanceState) { 2764fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen mParentView = inflater.inflate(R.layout.phone_favorites_fragment, container, false); 2776b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 2784fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen mListView = (PhoneFavoriteListView) mParentView.findViewById(R.id.contact_tile_list); 2796b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListView.setItemsCanFocus(true); 2806b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListView.setOnItemClickListener(this); 2816b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListView.setVerticalScrollBarEnabled(false); 2826b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT); 2836b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY); 28411ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee mListView.setOnItemSwipeListener(mContactTileAdapter); 2857639fe9a3ecc9c197718a9f81d8a745d2f660cb3Hongwei Wang mListView.setOnDragDropListener(mContactTileAdapter); 2866b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 2874911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang final ImageView dragShadowOverlay = 2884fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen (ImageView) mParentView.findViewById(R.id.contact_tile_drag_shadow_overlay); 2894911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang mListView.setDragShadowOverlay(dragShadowOverlay); 2904911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang 2914fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen mEmptyView = mParentView.findViewById(R.id.phone_no_favorites_view); 2924fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen 2934fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen mShowAllContactsInEmptyViewButton = mParentView.findViewById( 2944fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen R.id.show_all_contact_button_in_nofav); 295fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee prepareAllContactsButton(mShowAllContactsInEmptyViewButton); 29618e7fdd55f67e3636c161462cb54e7f5555a04deYorke Lee 2976091473941d277ed3746143c1ca9bffdfbe2bd94Christine Chen mShowAllContactsButton = inflater.inflate(R.layout.show_all_contact_button, mListView, 2986091473941d277ed3746143c1ca9bffdfbe2bd94Christine Chen false); 299fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee 300fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee prepareAllContactsButton(mShowAllContactsButton); 3016b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 3023eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee mContactTileFrame = mParentView.findViewById(R.id.contact_tile_frame); 3033eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee 3041f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen mTileInteractionTeaserView = (TileInteractionTeaserView) inflater.inflate( 3051f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen R.layout.tile_interactions_teaser_view, mListView, false); 3061f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen 30721299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee mAdapter = new PhoneFavoriteMergedAdapter(getActivity(), this, mContactTileAdapter, 3081f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen mCallLogAdapter, mShowAllContactsButton, mTileInteractionTeaserView); 3091f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen 3101f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen mTileInteractionTeaserView.setAdapter(mAdapter); 3116b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 3126b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListView.setAdapter(mAdapter); 3136b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 3146b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListView.setOnScrollListener(mScrollListener); 3156b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListView.setFastScrollEnabled(false); 3166b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee mListView.setFastScrollAlwaysVisible(false); 3176b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 3184fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen return mParentView; 3196b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 3206b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 321f420a5344995b2c450379159f679809690bc9880Yorke Lee public boolean hasFrequents() { 322f420a5344995b2c450379159f679809690bc9880Yorke Lee if (mContactTileAdapter == null) return false; 3236b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee return mContactTileAdapter.getNumFrequents() > 0; 3246b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 3256b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 3264fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen /* package */ void setEmptyViewVisibility(final boolean visible) { 3274fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen final int previousVisibility = mEmptyView.getVisibility(); 3284fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen final int newVisibility = visible ? View.VISIBLE : View.GONE; 3294fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen 3304fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen if (previousVisibility != newVisibility) { 3313eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee final RelativeLayout.LayoutParams params = (LayoutParams) mContactTileFrame 3323eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee .getLayoutParams(); 3333eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee params.height = visible ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT; 3343eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee mContactTileFrame.setLayoutParams(params); 335fe3fbd24097c51290b189f2788059c4083dd90a1Christine Chen mEmptyView.setVisibility(newVisibility); 3364fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen } 3374fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen } 3384fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen 3396b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 3406b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onStart() { 3416b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee super.onStart(); 3426b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 343dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee final Activity activity = getActivity(); 344dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee 345dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee try { 346dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee mActivityScrollListener = (OnListFragmentScrolledListener) activity; 347dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee } catch (ClassCastException e) { 348dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee throw new ClassCastException(activity.toString() 349dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee + " must implement OnListFragmentScrolledListener"); 350dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee } 3516b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 3528dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee try { 3538dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee mShowAllContactsListener = (OnShowAllContactsListener) activity; 3548dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee } catch (ClassCastException e) { 3558dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee throw new ClassCastException(activity.toString() 3568dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee + " must implement OnShowAllContactsListener"); 3578dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee } 3588dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee 3596b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee // Use initLoader() instead of restartLoader() to refraining unnecessary reload. 3606b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee // This method call implicitly assures ContactTileLoaderListener's onLoadFinished() will 3616b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee // be called, on which we'll check if "all" contacts should be reloaded again or not. 3626b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null, mContactTileLoaderListener); 363c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng getLoaderManager().initLoader(MISSED_CALL_LOADER, null, new MissedCallLogLoaderListener()); 3646b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 3656b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 3666b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee /** 3676b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * {@inheritDoc} 3686b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * 3696b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * This is only effective for elements provided by {@link #mContactTileAdapter}. 3706b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * {@link #mContactTileAdapter} has its own logic for click events. 3716b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee */ 3726b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee @Override 3736b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 3746b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee final int contactTileAdapterCount = mContactTileAdapter.getCount(); 3756b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee if (position <= contactTileAdapterCount) { 3766b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee Log.e(TAG, "onItemClick() event for unexpected position. " 3776b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee + "The position " + position + " is before \"all\" section. Ignored."); 3786b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 3796b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 3806b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 3816b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee /** 3826091473941d277ed3746143c1ca9bffdfbe2bd94Christine Chen * Gets called when user click on the show all contacts button. 3836b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee */ 3846091473941d277ed3746143c1ca9bffdfbe2bd94Christine Chen private void showAllContacts() { 3858dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee mShowAllContactsListener.onShowAllContacts(); 3866b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 3876b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 388dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee public void setListener(Listener listener) { 389dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee mListener = listener; 3906b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 3916b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 392dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee @Override 393dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee public void onVoicemailStatusFetched(Cursor statusCursor) { 3944dc32bdf10bff18acbc1964d289354556950d2ebYorke Lee // no-op 3956b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 3966b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 397dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee @Override 398dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee public void onCallsFetched(Cursor cursor) { 3994ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee animateListView(); 400dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee mCallLogAdapter.setLoading(false); 40121299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee 40221299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee // Save the date of the most recent call log item 40321299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee if (cursor != null && cursor.moveToFirst()) { 40421299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee mCurrentCallShortcutDate = cursor.getLong(CallLogQuery.DATE); 40521299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee } 40621299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee 407dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee mCallLogAdapter.changeCursor(cursor); 408dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee mAdapter.notifyDataSetChanged(); 4096b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 4106b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee 411dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee @Override 412dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee public void fetchCalls() { 41321299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee mCallLogQueryHandler.fetchCalls(CallLogQueryHandler.CALL_TYPE_ALL, mLastCallShortcutDate); 4146b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee } 41511ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee 41611ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee @Override 41711ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee public void onPause() { 41811ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee // If there are any pending contact entries that are to be removed, remove them 41911ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee mContactTileAdapter.removePendingContactEntry(); 4203b9d09c50b6ed52cbfe6d87cee06ecef5116d799Yorke Lee // Wipe the cache to refresh the call shortcut item. This is not that expensive because 4213b9d09c50b6ed52cbfe6d87cee06ecef5116d799Yorke Lee // it only contains one item. 4223b9d09c50b6ed52cbfe6d87cee06ecef5116d799Yorke Lee mCallLogAdapter.invalidateCache(); 42311ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee super.onPause(); 42411ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee } 425c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 426c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee /** 427c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee * Saves the current view offsets into memory 428c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee */ 429c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee @SuppressWarnings("unchecked") 4304ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee private void saveOffsets(int removedItemHeight) { 431c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final int firstVisiblePosition = mListView.getFirstVisiblePosition(); 432c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee if (DEBUG) { 433c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee Log.d(TAG, "Child count : " + mListView.getChildCount()); 434c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 435c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee for (int i = 0; i < mListView.getChildCount(); i++) { 436c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final View child = mListView.getChildAt(i); 437c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final int position = firstVisiblePosition + i; 438c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final long itemId = mAdapter.getItemId(position); 439c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final int itemViewType = mAdapter.getItemViewType(position); 440c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP) { 441c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee // This is a tiled row, so save horizontal offsets instead 442c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee saveHorizontalOffsets((ContactTileRow) child, (ArrayList<ContactEntry>) 4434ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee mAdapter.getItem(position)); 444c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 445c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee if (DEBUG) { 446c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee Log.d(TAG, "Saving itemId: " + itemId + " for listview child " + i + " Top: " 447c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee + child.getTop()); 448c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 449c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee mItemIdTopMap.put(itemId, child.getTop()); 450c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 4514ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee 4524ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee mItemIdTopMap.put(KEY_REMOVED_ITEM_HEIGHT, removedItemHeight); 453c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 454c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 4554ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee private void saveHorizontalOffsets(ContactTileRow row, ArrayList<ContactEntry> list) { 456c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee for (int i = 0; i < list.size(); i++) { 457c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final View child = row.getChildAt(i); 458c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final ContactEntry entry = list.get(i); 459c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id); 460c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee if (DEBUG) { 461c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee Log.d(TAG, "Saving itemId: " + itemId + " for tileview child " + i + " Left: " 462c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee + child.getTop()); 463c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 464c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee mItemIdLeftMap.put(itemId, child.getLeft()); 465c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 466c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 467c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 468c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee /* 469c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee * Performs a animations for a row of tiles 470c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee */ 471c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee private void performHorizontalAnimations(ContactTileRow row, ArrayList<ContactEntry> list, 472c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee long[] idsInPlace) { 473c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee if (mItemIdLeftMap.isEmpty()) { 474c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee return; 475c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 4765b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang final AnimatorSet animSet = new AnimatorSet(); 4775b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang final ArrayList<Animator> animators = new ArrayList<Animator>(); 478c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee for (int i = 0; i < list.size(); i++) { 479c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final View child = row.getChildAt(i); 480c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final ContactEntry entry = list.get(i); 481c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id); 482c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 4834911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang if (containsId(idsInPlace, itemId)) { 4845b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang animators.add(ObjectAnimator.ofFloat( 4855b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang child, "alpha", 0.0f, 1.0f)); 4864911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang break; 4875b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang } else { 4885b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang Integer startLeft = mItemIdLeftMap.get(itemId); 4895b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang int left = child.getLeft(); 4905b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang if (startLeft != null) { 4915b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang if (startLeft != left) { 4925b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang int delta = startLeft - left; 4935b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang if (DEBUG) { 4945b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang Log.d(TAG, "Found itemId: " + itemId + " for tileview child " + i + 4955b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang " Left: " + left + 4965b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang " Delta: " + delta); 4975b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang } 4985b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang animators.add(ObjectAnimator.ofFloat( 4995b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang child, "translationX", delta, 0.0f)); 5005b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang } 5015b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang } else { 5025b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang // In case the last square row is pushed up from the non-square section. 5035b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang animators.add(ObjectAnimator.ofFloat( 5045b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang child, "translationX", left, 0.0f)); 5055b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang } 506c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 507c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 5085b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang if (animators.size() > 0) { 5095b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang animSet.setDuration(mAnimationDuration).playTogether(animators); 5105b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang animSet.start(); 5115b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang } 512c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 513c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 514c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee /* 515c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee * Performs animations for the list view. If the list item is a row of tiles, horizontal 516c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee * animations will be performed instead. 517c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee */ 518c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee private void animateListView(final long... idsInPlace) { 51920d682f9a586da495f180bfb6a445520d027c74dHongwei Wang if (mItemIdTopMap.isEmpty()) { 520c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee // Don't do animations if the database is being queried for the first time and 521c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee // the previous item offsets have not been cached, or the user hasn't done anything 522c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee // (dragging, swiping etc) that requires an animation. 523c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee return; 524c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 5254ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee 5264ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee final int removedItemHeight = mItemIdTopMap.get(KEY_REMOVED_ITEM_HEIGHT); 5274ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee 528c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final ViewTreeObserver observer = mListView.getViewTreeObserver(); 529c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 530c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee @SuppressWarnings("unchecked") 531c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee @Override 532c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee public boolean onPreDraw() { 533c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee observer.removeOnPreDrawListener(this); 534c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final int firstVisiblePosition = mListView.getFirstVisiblePosition(); 5355b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang final AnimatorSet animSet = new AnimatorSet(); 5365b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang final ArrayList<Animator> animators = new ArrayList<Animator>(); 537c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee for (int i = 0; i < mListView.getChildCount(); i++) { 538c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final View child = mListView.getChildAt(i); 539c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee int position = firstVisiblePosition + i; 540c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final int itemViewType = mAdapter.getItemViewType(position); 541c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP) { 542c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee // This is a tiled row, so perform horizontal animations instead 543c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee performHorizontalAnimations((ContactTileRow) child, ( 544c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee ArrayList<ContactEntry>) mAdapter.getItem(position), idsInPlace); 545c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 546c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 547c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee final long itemId = mAdapter.getItemId(position); 548c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 5494911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang if (containsId(idsInPlace, itemId)) { 5505b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang animators.add(ObjectAnimator.ofFloat( 5515b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang child, "alpha", 0.0f, 1.0f)); 5525b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang break; 553f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira } else { 554f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira Integer startTop = mItemIdTopMap.get(itemId); 555f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira final int top = child.getTop(); 556f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira int delta = 0; 557f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira if (startTop != null) { 558f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira if (startTop != top) { 559f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira delta = startTop - top; 560f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira } 561f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira } else if (!mItemIdLeftMap.containsKey(itemId)) { 562f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira // Animate new views along with the others. The catch is that they did 563f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira // not exist in the start state, so we must calculate their starting 564f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira // position based on neighboring views. 5654ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee 5664ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee final int itemHeight; 5674ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee if (removedItemHeight == 0) { 5684ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee itemHeight = child.getHeight() + mListView.getDividerHeight(); 5694ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee } else { 5704ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee itemHeight = removedItemHeight; 5714ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee } 5724ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee startTop = top + (i > 0 ? itemHeight : -itemHeight); 573f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira delta = startTop - top; 5745b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang } else { 57520d682f9a586da495f180bfb6a445520d027c74dHongwei Wang // In case the first non-square row is pushed down 5765b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang // from the square section. 5775b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang animators.add(ObjectAnimator.ofFloat( 57820d682f9a586da495f180bfb6a445520d027c74dHongwei Wang child, "alpha", 0.0f, 1.0f)); 5795b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang } 5805b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang if (DEBUG) { 5815b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang Log.d(TAG, "Found itemId: " + itemId + " for listview child " + i + 5825b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang " Top: " + top + 5835b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang " Delta: " + delta); 584f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira } 585f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira 586f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira if (delta != 0) { 5875b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang animators.add(ObjectAnimator.ofFloat( 5885b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang child, "translationY", delta, 0.0f)); 589f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira } 590c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 591c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 5925b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang 5935b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang if (animators.size() > 0) { 5945b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang animSet.setDuration(mAnimationDuration).playTogether(animators); 5955b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang animSet.start(); 5965b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang } 5975b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang 598c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee mItemIdTopMap.clear(); 599c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee mItemIdLeftMap.clear(); 600c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee return true; 601c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 602c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee }); 603c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 604c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 605c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee private boolean containsId(long[] ids, long target) { 606c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee // Linear search on array is fine because this is typically only 0-1 elements long 607c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee for (int i = 0; i < ids.length; i++) { 608c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee if (ids[i] == target) { 609c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee return true; 610c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 611c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 612c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee return false; 613c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 614c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 615c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee @Override 616c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee public void onDataSetChangedForAnimation(long... idsInPlace) { 617c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee animateListView(idsInPlace); 618c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 619c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee 620c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee @Override 621c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee public void cacheOffsetsForDatasetChange() { 6224ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee saveOffsets(0); 623c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee } 62421299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee 6254ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee public void dismissShortcut(int height) { 6264ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee saveOffsets(height); 62721299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee mLastCallShortcutDate = mCurrentCallShortcutDate; 62821299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee final SharedPreferences prefs = getActivity().getSharedPreferences( 62921299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee DialtactsActivity.SHARED_PREFS_NAME, Context.MODE_PRIVATE); 63021299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee prefs.edit().putLong(KEY_LAST_DISMISSED_CALL_SHORTCUT_DATE, mLastCallShortcutDate) 63121299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee .apply(); 63221299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee fetchCalls(); 63321299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee } 634fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee 635fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee /** 636fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee * Returns a view that is laid out and styled to look like a regular contact, with the correct 637fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee * click behavior (to launch the all contacts activity when it is clicked). 638fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee */ 639fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee private View prepareAllContactsButton(View v) { 640fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee final ContactListItemView view = (ContactListItemView) v; 641fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee view.setOnClickListener(new OnClickListener() { 642fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee @Override 643fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee public void onClick(View view) { 644fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee showAllContacts(); 645fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee } 646fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee }); 647fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee 648fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee view.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT); 649fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee final Resources resources = getResources(); 650fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee view.setBackgroundResource(R.drawable.contact_list_item_background); 651fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee 652fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee view.setPaddingRelative( 653fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee resources.getDimensionPixelSize(R.dimen.favorites_row_start_padding), 654fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee resources.getDimensionPixelSize(R.dimen.favorites_row_end_padding), 655fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee resources.getDimensionPixelSize(R.dimen.favorites_row_top_padding), 656fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee resources.getDimensionPixelSize(R.dimen.favorites_row_bottom_padding)); 657fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee 658fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee view.setDisplayName(resources.getString(R.string.show_all_contacts_button_text)); 659fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee view.setDrawableResource(R.drawable.list_item_avatar_bg, 660fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee R.drawable.ic_menu_all_contacts_dk); 661fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee return view; 662fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee } 6636b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee} 664