1edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng/*
2edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng * Copyright (C) 2010 The Android Open Source Project
3edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng *
4edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
5edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng * you may not use this file except in compliance with the License.
6edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng * You may obtain a copy of the License at
7edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng *
8edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
9edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng *
10edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng * Unless required by applicable law or agreed to in writing, software
11edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
12edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng * See the License for the specific language governing permissions and
14edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng * limitations under the License.
15edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng */
16edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
17edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengpackage com.android.contacts.common.list;
18edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
19edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.app.Activity;
20edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.app.LoaderManager;
21edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.app.LoaderManager.LoaderCallbacks;
22edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.content.Context;
23edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.content.CursorLoader;
24edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.content.Intent;
25edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.content.Loader;
2687e29f060b8fe7a1f8794955ded14617214af0edZheng Fuimport android.content.res.Resources;
27edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.database.Cursor;
28edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.os.Bundle;
29edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.os.Handler;
30edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.os.Message;
31edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.os.Parcelable;
32edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.provider.ContactsContract.Directory;
33edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.text.TextUtils;
34edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.view.LayoutInflater;
35edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.view.MotionEvent;
36edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.view.View;
37edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.view.View.OnFocusChangeListener;
38edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.view.View.OnTouchListener;
39edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.view.ViewGroup;
40edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.view.inputmethod.InputMethodManager;
41edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.widget.AbsListView;
42edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.widget.AbsListView.OnScrollListener;
43edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.widget.AdapterView;
44edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.widget.AdapterView.OnItemClickListener;
45edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport android.widget.ListView;
46edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
47edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport com.android.common.widget.CompositeCursorAdapter.Partition;
48edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport com.android.contacts.common.R;
4987e29f060b8fe7a1f8794955ded14617214af0edZheng Fuimport com.android.contacts.common.ContactPhotoManager;
50edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengimport com.android.contacts.common.preference.ContactsPreferences;
5187e29f060b8fe7a1f8794955ded14617214af0edZheng Fuimport com.android.contacts.common.util.ContactListViewUtils;
5287e29f060b8fe7a1f8794955ded14617214af0edZheng Fuimport com.android.contacts.common.util.SchedulingUtils;
53f5d6a7cf8f7f9cb80a65ad2d70634f25191c7e95Sai Cheemalapatiimport com.android.dialerbind.analytics.AnalyticsFragment;
54edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
559f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglioimport java.util.Locale;
569f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio
57edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng/**
58edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng * Common base class for various contact-related list fragments.
59edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng */
60edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Chengpublic abstract class ContactEntryListFragment<T extends ContactEntryListAdapter>
61f5d6a7cf8f7f9cb80a65ad2d70634f25191c7e95Sai Cheemalapati        extends AnalyticsFragment
62edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        implements OnItemClickListener, OnScrollListener, OnFocusChangeListener, OnTouchListener,
63edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                LoaderCallbacks<Cursor> {
64edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String TAG = "ContactEntryListFragment";
65edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
66edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    // TODO: Make this protected. This should not be used from the PeopleActivity but
67edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    // instead use the new startActivityWithResultFromFragment API
68edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public static final int ACTIVITY_REQUEST_CODE_PICKER = 1;
69edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
70edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_LIST_STATE = "liststate";
71edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_SECTION_HEADER_DISPLAY_ENABLED = "sectionHeaderDisplayEnabled";
72edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_PHOTO_LOADER_ENABLED = "photoLoaderEnabled";
73edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_QUICK_CONTACT_ENABLED = "quickContactEnabled";
74fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee    private static final String KEY_ADJUST_SELECTION_BOUNDS_ENABLED =
75fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee            "adjustSelectionBoundsEnabled";
76edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_INCLUDE_PROFILE = "includeProfile";
77edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_SEARCH_MODE = "searchMode";
78edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_VISIBLE_SCROLLBAR_ENABLED = "visibleScrollbarEnabled";
79edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_SCROLLBAR_POSITION = "scrollbarPosition";
80edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_QUERY_STRING = "queryString";
81edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_DIRECTORY_SEARCH_MODE = "directorySearchMode";
82edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_SELECTION_VISIBLE = "selectionVisible";
83edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_REQUEST = "request";
84edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_DARK_THEME = "darkTheme";
85edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_LEGACY_COMPATIBILITY = "legacyCompatibility";
86edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String KEY_DIRECTORY_RESULT_LIMIT = "directoryResultLimit";
87edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
88edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final String DIRECTORY_ID_ARG_KEY = "directoryId";
89edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
90edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final int DIRECTORY_LOADER_ID = -1;
91edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
92edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final int DIRECTORY_SEARCH_DELAY_MILLIS = 300;
93edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final int DIRECTORY_SEARCH_MESSAGE = 1;
94edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
95edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final int DEFAULT_DIRECTORY_RESULT_LIMIT = 20;
96edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
97edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mSectionHeaderDisplayEnabled;
98edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mPhotoLoaderEnabled;
99edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mQuickContactEnabled = true;
100fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee    private boolean mAdjustSelectionBoundsEnabled = true;
101edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mIncludeProfile;
102edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mSearchMode;
103edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mVisibleScrollbarEnabled;
104f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee    private boolean mShowEmptyListForEmptyQuery;
1059f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio    private int mVerticalScrollbarPosition = getDefaultVerticalScrollbarPosition();
106edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private String mQueryString;
107edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private int mDirectorySearchMode = DirectoryListLoader.SEARCH_MODE_NONE;
108edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mSelectionVisible;
109edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mLegacyCompatibility;
110edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
111edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mEnabled = true;
112edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
113edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private T mAdapter;
114edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private View mView;
115edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private ListView mListView;
116edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
117edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
118edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Used for keeping track of the scroll state of the list.
119edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
120edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private Parcelable mListState;
121edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
122edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private int mDisplayOrder;
123edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private int mSortOrder;
124edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private int mDirectoryResultLimit = DEFAULT_DIRECTORY_RESULT_LIMIT;
125edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
126edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private ContactPhotoManager mPhotoManager;
127edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private ContactsPreferences mContactsPrefs;
128edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
129edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mForceLoad;
130edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
131edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mDarkTheme;
132edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
133edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected boolean mUserProfileExists;
134edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
135edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final int STATUS_NOT_LOADED = 0;
136edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final int STATUS_LOADING = 1;
137edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private static final int STATUS_LOADED = 2;
138edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
139edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private int mDirectoryListStatus = STATUS_NOT_LOADED;
140edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
141edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
142edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Indicates whether we are doing the initial complete load of data (false) or
143edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * a refresh caused by a change notification (true)
144edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
145edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private boolean mLoadPriorityDirectoriesOnly;
146edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
147edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private Context mContext;
148edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
149edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private LoaderManager mLoaderManager;
150edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
151edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private Handler mDelayedDirectorySearchHandler = new Handler() {
152edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        @Override
153edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        public void handleMessage(Message msg) {
154edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (msg.what == DIRECTORY_SEARCH_MESSAGE) {
155edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                loadDirectoryPartition(msg.arg1, (DirectoryPartition) msg.obj);
156edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
157edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
158edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    };
1599f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio    private int defaultVerticalScrollbarPosition;
160edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
161edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected abstract View inflateView(LayoutInflater inflater, ViewGroup container);
162edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected abstract T createListAdapter();
163edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
164edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
165edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * @param position Please note that the position is already adjusted for
166edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     *            header views, so "0" means the first list item below header
167edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     *            views.
168edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
169edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected abstract void onItemClick(int position, long id);
170edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
171edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
172edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onAttach(Activity activity) {
173edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        super.onAttach(activity);
174edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        setContext(activity);
175edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        setLoaderManager(super.getLoaderManager());
176edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
177edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
178edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
179edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Sets a context for the fragment in the unit test environment.
180edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
181edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setContext(Context context) {
182edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mContext = context;
183edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        configurePhotoLoader();
184edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
185edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
186edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public Context getContext() {
187edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mContext;
188edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
189edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
190edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setEnabled(boolean enabled) {
191edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mEnabled != enabled) {
192edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mEnabled = enabled;
193edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (mAdapter != null) {
194edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                if (mEnabled) {
195edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    reloadData();
196edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                } else {
197edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    mAdapter.clearPartitions();
198edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                }
199edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
200edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
201edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
202edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
203edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
204edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Overrides a loader manager for use in unit tests.
205edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
206edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setLoaderManager(LoaderManager loaderManager) {
207edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mLoaderManager = loaderManager;
208edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
209edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
210edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
211edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public LoaderManager getLoaderManager() {
212edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mLoaderManager;
213edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
214edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
215edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public T getAdapter() {
216edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mAdapter;
217edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
218edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
219edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
220edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public View getView() {
221edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mView;
222edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
223edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
224edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public ListView getListView() {
225edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mListView;
226edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
227edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
228edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
229edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onSaveInstanceState(Bundle outState) {
230edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        super.onSaveInstanceState(outState);
231edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putBoolean(KEY_SECTION_HEADER_DISPLAY_ENABLED, mSectionHeaderDisplayEnabled);
232edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putBoolean(KEY_PHOTO_LOADER_ENABLED, mPhotoLoaderEnabled);
233edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putBoolean(KEY_QUICK_CONTACT_ENABLED, mQuickContactEnabled);
234fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee        outState.putBoolean(KEY_ADJUST_SELECTION_BOUNDS_ENABLED, mAdjustSelectionBoundsEnabled);
235edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putBoolean(KEY_INCLUDE_PROFILE, mIncludeProfile);
236edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putBoolean(KEY_SEARCH_MODE, mSearchMode);
237edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putBoolean(KEY_VISIBLE_SCROLLBAR_ENABLED, mVisibleScrollbarEnabled);
238edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putInt(KEY_SCROLLBAR_POSITION, mVerticalScrollbarPosition);
239edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putInt(KEY_DIRECTORY_SEARCH_MODE, mDirectorySearchMode);
240edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putBoolean(KEY_SELECTION_VISIBLE, mSelectionVisible);
241edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putBoolean(KEY_LEGACY_COMPATIBILITY, mLegacyCompatibility);
242edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putString(KEY_QUERY_STRING, mQueryString);
243edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putInt(KEY_DIRECTORY_RESULT_LIMIT, mDirectoryResultLimit);
244edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        outState.putBoolean(KEY_DARK_THEME, mDarkTheme);
245edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
246edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mListView != null) {
247edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            outState.putParcelable(KEY_LIST_STATE, mListView.onSaveInstanceState());
248edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
249edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
250edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
251edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
252edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onCreate(Bundle savedState) {
253edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        super.onCreate(savedState);
2540631174430c169d84675123346797654f4e62b5cBrian Attwell        restoreSavedState(savedState);
25544248ce0d1c4abe9f6b2c484464f131819c0ded5Yorke Lee        mAdapter = createListAdapter();
256edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mContactsPrefs = new ContactsPreferences(mContext);
257edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
258edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
259edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void restoreSavedState(Bundle savedState) {
260edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (savedState == null) {
261edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            return;
262edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
263edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
264edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mSectionHeaderDisplayEnabled = savedState.getBoolean(KEY_SECTION_HEADER_DISPLAY_ENABLED);
265edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mPhotoLoaderEnabled = savedState.getBoolean(KEY_PHOTO_LOADER_ENABLED);
266edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mQuickContactEnabled = savedState.getBoolean(KEY_QUICK_CONTACT_ENABLED);
267fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee        mAdjustSelectionBoundsEnabled = savedState.getBoolean(KEY_ADJUST_SELECTION_BOUNDS_ENABLED);
268edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mIncludeProfile = savedState.getBoolean(KEY_INCLUDE_PROFILE);
269edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mSearchMode = savedState.getBoolean(KEY_SEARCH_MODE);
270edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mVisibleScrollbarEnabled = savedState.getBoolean(KEY_VISIBLE_SCROLLBAR_ENABLED);
271edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mVerticalScrollbarPosition = savedState.getInt(KEY_SCROLLBAR_POSITION);
272edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDirectorySearchMode = savedState.getInt(KEY_DIRECTORY_SEARCH_MODE);
273edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mSelectionVisible = savedState.getBoolean(KEY_SELECTION_VISIBLE);
274edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mLegacyCompatibility = savedState.getBoolean(KEY_LEGACY_COMPATIBILITY);
275edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mQueryString = savedState.getString(KEY_QUERY_STRING);
276edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDirectoryResultLimit = savedState.getInt(KEY_DIRECTORY_RESULT_LIMIT);
277edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDarkTheme = savedState.getBoolean(KEY_DARK_THEME);
278edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
279edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        // Retrieve list state. This will be applied in onLoadFinished
280edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mListState = savedState.getParcelable(KEY_LIST_STATE);
281edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
282edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
283edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
284edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onStart() {
285edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        super.onStart();
286edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
287edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mContactsPrefs.registerChangeListener(mPreferencesChangeListener);
288edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
289edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mForceLoad = loadPreferences();
290edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
291edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDirectoryListStatus = STATUS_NOT_LOADED;
292edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mLoadPriorityDirectoriesOnly = true;
293edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
294edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        startLoading();
295edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
296edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
297edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void startLoading() {
298edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mAdapter == null) {
299edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            // The method was called before the fragment was started
300edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            return;
301edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
302edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
303edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        configureAdapter();
304edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        int partitionCount = mAdapter.getPartitionCount();
305edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        for (int i = 0; i < partitionCount; i++) {
306edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            Partition partition = mAdapter.getPartition(i);
307edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (partition instanceof DirectoryPartition) {
308edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                DirectoryPartition directoryPartition = (DirectoryPartition)partition;
309edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                if (directoryPartition.getStatus() == DirectoryPartition.STATUS_NOT_LOADED) {
310edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    if (directoryPartition.isPriorityDirectory() || !mLoadPriorityDirectoriesOnly) {
311edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                        startLoadingDirectoryPartition(i);
312edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    }
313edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                }
314edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            } else {
315edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                getLoaderManager().initLoader(i, null, this);
316edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
317edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
318edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
319edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        // Next time this method is called, we should start loading non-priority directories
320edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mLoadPriorityDirectoriesOnly = false;
321edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
322edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
323edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
324edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
325edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (id == DIRECTORY_LOADER_ID) {
326edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            DirectoryListLoader loader = new DirectoryListLoader(mContext);
327edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            loader.setDirectorySearchMode(mAdapter.getDirectorySearchMode());
328edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            loader.setLocalInvisibleDirectoryEnabled(
329edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    ContactEntryListAdapter.LOCAL_INVISIBLE_DIRECTORY_ENABLED);
330edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            return loader;
331edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        } else {
332e31b07390729cced594404410efb4448f94a95cbJay Shrauner            CursorLoader loader = createCursorLoader(mContext);
333edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            long directoryId = args != null && args.containsKey(DIRECTORY_ID_ARG_KEY)
334edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    ? args.getLong(DIRECTORY_ID_ARG_KEY)
335edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    : Directory.DEFAULT;
336edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mAdapter.configureLoader(loader, directoryId);
337edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            return loader;
338edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
339edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
340edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
341e31b07390729cced594404410efb4448f94a95cbJay Shrauner    public CursorLoader createCursorLoader(Context context) {
342e31b07390729cced594404410efb4448f94a95cbJay Shrauner        return new CursorLoader(context, null, null, null, null, null);
343edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
344edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
345edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private void startLoadingDirectoryPartition(int partitionIndex) {
346edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        DirectoryPartition partition = (DirectoryPartition)mAdapter.getPartition(partitionIndex);
347edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        partition.setStatus(DirectoryPartition.STATUS_LOADING);
348edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        long directoryId = partition.getDirectoryId();
349edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mForceLoad) {
350edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (directoryId == Directory.DEFAULT) {
351edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                loadDirectoryPartition(partitionIndex, partition);
352edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            } else {
353edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                loadDirectoryPartitionDelayed(partitionIndex, partition);
354edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
355edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        } else {
356edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            Bundle args = new Bundle();
357edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            args.putLong(DIRECTORY_ID_ARG_KEY, directoryId);
358edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            getLoaderManager().initLoader(partitionIndex, args, this);
359edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
360edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
361edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
362edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
363edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Queues up a delayed request to search the specified directory. Since
364edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * directory search will likely introduce a lot of network traffic, we want
365edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * to wait for a pause in the user's typing before sending a directory request.
366edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
367edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private void loadDirectoryPartitionDelayed(int partitionIndex, DirectoryPartition partition) {
368edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDelayedDirectorySearchHandler.removeMessages(DIRECTORY_SEARCH_MESSAGE, partition);
369edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        Message msg = mDelayedDirectorySearchHandler.obtainMessage(
370edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                DIRECTORY_SEARCH_MESSAGE, partitionIndex, 0, partition);
371edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDelayedDirectorySearchHandler.sendMessageDelayed(msg, DIRECTORY_SEARCH_DELAY_MILLIS);
372edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
373edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
374edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
375edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Loads the directory partition.
376edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
377edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void loadDirectoryPartition(int partitionIndex, DirectoryPartition partition) {
378edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        Bundle args = new Bundle();
379edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        args.putLong(DIRECTORY_ID_ARG_KEY, partition.getDirectoryId());
380edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        getLoaderManager().restartLoader(partitionIndex, args, this);
381edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
382edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
383edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
384edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Cancels all queued directory loading requests.
385edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
386edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private void removePendingDirectorySearchRequests() {
387edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDelayedDirectorySearchHandler.removeMessages(DIRECTORY_SEARCH_MESSAGE);
388edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
389edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
390edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
391edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
392edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (!mEnabled) {
393edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            return;
394edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
395edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
396edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        int loaderId = loader.getId();
397edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (loaderId == DIRECTORY_LOADER_ID) {
398edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mDirectoryListStatus = STATUS_LOADED;
399edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mAdapter.changeDirectories(data);
400edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            startLoading();
401edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        } else {
402edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            onPartitionLoaded(loaderId, data);
403edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (isSearchMode()) {
404edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                int directorySearchMode = getDirectorySearchMode();
405edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                if (directorySearchMode != DirectoryListLoader.SEARCH_MODE_NONE) {
406edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    if (mDirectoryListStatus == STATUS_NOT_LOADED) {
407edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                        mDirectoryListStatus = STATUS_LOADING;
408edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                        getLoaderManager().initLoader(DIRECTORY_LOADER_ID, null, this);
409edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    } else {
410edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                        startLoading();
411edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    }
412edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                }
413edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            } else {
414edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mDirectoryListStatus = STATUS_NOT_LOADED;
415edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                getLoaderManager().destroyLoader(DIRECTORY_LOADER_ID);
416edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
417edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
418edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
419edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
420edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onLoaderReset(Loader<Cursor> loader) {
421edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
422edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
423edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void onPartitionLoaded(int partitionIndex, Cursor data) {
424edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (partitionIndex >= mAdapter.getPartitionCount()) {
425edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            // When we get unsolicited data, ignore it.  This could happen
426edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            // when we are switching from search mode to the default mode.
427edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            return;
428edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
429edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
430edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.changeCursor(partitionIndex, data);
431edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        setProfileHeader();
432edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
433edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (!isLoading()) {
434edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            completeRestoreInstanceState();
435edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
436edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
437edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
438edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public boolean isLoading() {
439edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mAdapter != null && mAdapter.isLoading()) {
440edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            return true;
441edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
442edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
443edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (isLoadingDirectoryList()) {
444edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            return true;
445edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
446edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
447edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return false;
448edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
449edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
450edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public boolean isLoadingDirectoryList() {
451edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return isSearchMode() && getDirectorySearchMode() != DirectoryListLoader.SEARCH_MODE_NONE
452edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                && (mDirectoryListStatus == STATUS_NOT_LOADED
453edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                        || mDirectoryListStatus == STATUS_LOADING);
454edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
455edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
456edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
457edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onStop() {
458edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        super.onStop();
459edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mContactsPrefs.unregisterChangeListener();
460edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.clearPartitions();
461edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
462edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
463edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void reloadData() {
464edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        removePendingDirectorySearchRequests();
465edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.onDataReload();
466edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mLoadPriorityDirectoriesOnly = true;
467edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mForceLoad = true;
468edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        startLoading();
469edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
470edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
471edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
472edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Shows a view at the top of the list with a pseudo local profile prompting the user to add
473edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * a local profile. Default implementation does nothing.
474edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
475edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void setProfileHeader() {
476edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mUserProfileExists = false;
477edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
478edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
479edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
480edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Provides logic that dismisses this fragment. The default implementation
481edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * does nothing.
482edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
483edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void finish() {
484edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
485edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
486edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setSectionHeaderDisplayEnabled(boolean flag) {
487edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mSectionHeaderDisplayEnabled != flag) {
488edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mSectionHeaderDisplayEnabled = flag;
489edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (mAdapter != null) {
490edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mAdapter.setSectionHeaderDisplayEnabled(flag);
491edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
492edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            configureVerticalScrollbar();
493edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
494edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
495edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
496edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public boolean isSectionHeaderDisplayEnabled() {
497edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mSectionHeaderDisplayEnabled;
498edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
499edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
500edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setVisibleScrollbarEnabled(boolean flag) {
501edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mVisibleScrollbarEnabled != flag) {
502edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mVisibleScrollbarEnabled = flag;
503edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            configureVerticalScrollbar();
504edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
505edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
506edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
507edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public boolean isVisibleScrollbarEnabled() {
508edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mVisibleScrollbarEnabled;
509edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
510edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
511edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setVerticalScrollbarPosition(int position) {
512edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mVerticalScrollbarPosition != position) {
513edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mVerticalScrollbarPosition = position;
514edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            configureVerticalScrollbar();
515edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
516edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
517edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
518edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private void configureVerticalScrollbar() {
519edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        boolean hasScrollbar = isVisibleScrollbarEnabled() && isSectionHeaderDisplayEnabled();
520edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
521edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mListView != null) {
522edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mListView.setFastScrollEnabled(hasScrollbar);
523edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mListView.setFastScrollAlwaysVisible(hasScrollbar);
524edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mListView.setVerticalScrollbarPosition(mVerticalScrollbarPosition);
525edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
526edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
527edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
528edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
529edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setPhotoLoaderEnabled(boolean flag) {
530edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mPhotoLoaderEnabled = flag;
531edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        configurePhotoLoader();
532edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
533edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
534edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public boolean isPhotoLoaderEnabled() {
535edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mPhotoLoaderEnabled;
536edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
537edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
538edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
539edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Returns true if the list is supposed to visually highlight the selected item.
540edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
541edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public boolean isSelectionVisible() {
542edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mSelectionVisible;
543edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
544edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
545edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setSelectionVisible(boolean flag) {
546edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        this.mSelectionVisible = flag;
547edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
548edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
549edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setQuickContactEnabled(boolean flag) {
550edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        this.mQuickContactEnabled = flag;
551edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
552edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
553fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee    public void setAdjustSelectionBoundsEnabled(boolean flag) {
554fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee        mAdjustSelectionBoundsEnabled = flag;
555fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee    }
556fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee
557edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setIncludeProfile(boolean flag) {
558edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mIncludeProfile = flag;
559edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if(mAdapter != null) {
560edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mAdapter.setIncludeProfile(flag);
561edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
562edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
563edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
564edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
565f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee     * Enter/exit search mode. This is method is tightly related to the current query, and should
566f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee     * only be called by {@link #setQueryString}.
567edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     *
568edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Also note this method doesn't call {@link #reloadData()}; {@link #setQueryString} does it.
569edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
570edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void setSearchMode(boolean flag) {
571edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mSearchMode != flag) {
572edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mSearchMode = flag;
573edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            setSectionHeaderDisplayEnabled(!mSearchMode);
574edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
575edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (!flag) {
576edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mDirectoryListStatus = STATUS_NOT_LOADED;
577edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                getLoaderManager().destroyLoader(DIRECTORY_LOADER_ID);
578edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
579edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
580edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (mAdapter != null) {
581edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mAdapter.setSearchMode(flag);
582edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
583edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mAdapter.clearPartitions();
584edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                if (!flag) {
585edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    // If we are switching from search to regular display, remove all directory
586edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    // partitions after default one, assuming they are remote directories which
587edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    // should be cleaned up on exiting the search mode.
588edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    mAdapter.removeDirectoriesAfterDefault();
589edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                }
590edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mAdapter.configureDefaultPartition(false, flag);
591edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
592edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
593edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (mListView != null) {
594edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mListView.setFastScrollEnabled(!flag);
595edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
596edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
597edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
598edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
599edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public final boolean isSearchMode() {
600edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mSearchMode;
601edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
602edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
603edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public final String getQueryString() {
604edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mQueryString;
605edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
606edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
607edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setQueryString(String queryString, boolean delaySelection) {
608edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (!TextUtils.equals(mQueryString, queryString)) {
609f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee            if (mShowEmptyListForEmptyQuery && mAdapter != null && mListView != null) {
610f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee                if (TextUtils.isEmpty(mQueryString)) {
611f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee                    // Restore the adapter if the query used to be empty.
612f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee                    mListView.setAdapter(mAdapter);
613f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee                } else if (TextUtils.isEmpty(queryString)) {
614f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee                    // Instantly clear the list view if the new query is empty.
615f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee                    mListView.setAdapter(null);
616f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee                }
617f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee            }
618f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee
619edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mQueryString = queryString;
620f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee            setSearchMode(!TextUtils.isEmpty(mQueryString) || mShowEmptyListForEmptyQuery);
621edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
622edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (mAdapter != null) {
623edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mAdapter.setQueryString(queryString);
624edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                reloadData();
625edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
626edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
627edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
628edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
629f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee    public void setShowEmptyListForNullQuery(boolean show) {
630f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee        mShowEmptyListForEmptyQuery = show;
631f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee    }
632f2e1ee6eb6bd1b24d149b815ec283c8750e02558Andrew Lee
633a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    public int getDirectoryLoaderId() {
634a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        return DIRECTORY_LOADER_ID;
635a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    }
636a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
637edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public int getDirectorySearchMode() {
638edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mDirectorySearchMode;
639edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
640edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
641edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setDirectorySearchMode(int mode) {
642edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDirectorySearchMode = mode;
643edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
644edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
645edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public boolean isLegacyCompatibilityMode() {
646edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mLegacyCompatibility;
647edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
648edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
649edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setLegacyCompatibilityMode(boolean flag) {
650edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mLegacyCompatibility = flag;
651edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
652edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
653edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected int getContactNameDisplayOrder() {
654edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mDisplayOrder;
655edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
656edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
657edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void setContactNameDisplayOrder(int displayOrder) {
658edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDisplayOrder = displayOrder;
659edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mAdapter != null) {
660edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mAdapter.setContactNameDisplayOrder(displayOrder);
661edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
662edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
663edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
664edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public int getSortOrder() {
665edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mSortOrder;
666edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
667edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
668edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setSortOrder(int sortOrder) {
669edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mSortOrder = sortOrder;
670edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mAdapter != null) {
671edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mAdapter.setSortOrder(sortOrder);
672edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
673edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
674edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
675edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setDirectoryResultLimit(int limit) {
676edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDirectoryResultLimit = limit;
677edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
678edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
679edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected boolean loadPreferences() {
680edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        boolean changed = false;
681edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (getContactNameDisplayOrder() != mContactsPrefs.getDisplayOrder()) {
682edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder());
683edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            changed = true;
684edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
685edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
686edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (getSortOrder() != mContactsPrefs.getSortOrder()) {
687edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            setSortOrder(mContactsPrefs.getSortOrder());
688edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            changed = true;
689edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
690edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
691edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return changed;
692edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
693edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
694edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
695edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public View onCreateView(LayoutInflater inflater, ViewGroup container,
696edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            Bundle savedInstanceState) {
697edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        onCreateView(inflater, container);
698edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
699edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        boolean searchMode = isSearchMode();
700edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setSearchMode(searchMode);
701edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.configureDefaultPartition(false, searchMode);
702edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setPhotoLoader(mPhotoManager);
703edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mListView.setAdapter(mAdapter);
704edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
705edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (!isSearchMode()) {
706edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mListView.setFocusableInTouchMode(true);
707edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mListView.requestFocus();
708edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
709edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
710edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return mView;
711edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
712edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
713edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
714edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mView = inflateView(inflater, container);
715edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
716edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mListView = (ListView)mView.findViewById(android.R.id.list);
717edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mListView == null) {
718edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            throw new RuntimeException(
719edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    "Your content must have a ListView whose id attribute is " +
720edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                    "'android.R.id.list'");
721edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
722edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
723edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        View emptyView = mView.findViewById(android.R.id.empty);
724edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (emptyView != null) {
725edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mListView.setEmptyView(emptyView);
726edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
727edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
728edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mListView.setOnItemClickListener(this);
729edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mListView.setOnFocusChangeListener(this);
730edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mListView.setOnTouchListener(this);
731edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mListView.setFastScrollEnabled(!isSearchMode());
732edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
733edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        // Tell list view to not show dividers. We'll do it ourself so that we can *not* show
734edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        // them when an A-Z headers is visible.
735edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mListView.setDividerHeight(0);
736edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
737edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        // We manually save/restore the listview state
738edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mListView.setSaveEnabled(false);
739edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
740edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        configureVerticalScrollbar();
741edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        configurePhotoLoader();
742c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell
743c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell        getAdapter().setFragmentRootView(getView());
74484a652ef252493066a8e09fd5110472158e7b568Brian Attwell
74584a652ef252493066a8e09fd5110472158e7b568Brian Attwell        ContactListViewUtils.applyCardPaddingToView(getResources(), mListView, mView);
74684a652ef252493066a8e09fd5110472158e7b568Brian Attwell    }
74784a652ef252493066a8e09fd5110472158e7b568Brian Attwell
74884a652ef252493066a8e09fd5110472158e7b568Brian Attwell    @Override
74984a652ef252493066a8e09fd5110472158e7b568Brian Attwell    public void onHiddenChanged(boolean hidden) {
75084a652ef252493066a8e09fd5110472158e7b568Brian Attwell        super.onHiddenChanged(hidden);
75184a652ef252493066a8e09fd5110472158e7b568Brian Attwell        if (getActivity() != null && getView() != null && !hidden) {
75284a652ef252493066a8e09fd5110472158e7b568Brian Attwell            // If the padding was last applied when in a hidden state, it may have been applied
75384a652ef252493066a8e09fd5110472158e7b568Brian Attwell            // incorrectly. Therefore we need to reapply it.
75484a652ef252493066a8e09fd5110472158e7b568Brian Attwell            ContactListViewUtils.applyCardPaddingToView(getResources(), mListView, getView());
75584a652ef252493066a8e09fd5110472158e7b568Brian Attwell        }
756edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
757edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
758edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void configurePhotoLoader() {
759edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (isPhotoLoaderEnabled() && mContext != null) {
760edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (mPhotoManager == null) {
761edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mPhotoManager = ContactPhotoManager.getInstance(mContext);
762edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
763edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (mListView != null) {
764edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mListView.setOnScrollListener(this);
765edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
766edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            if (mAdapter != null) {
767edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mAdapter.setPhotoLoader(mPhotoManager);
768edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            }
769edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
770edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
771edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
772edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void configureAdapter() {
773edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mAdapter == null) {
774edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            return;
775edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
776edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
777edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setQuickContactEnabled(mQuickContactEnabled);
778fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee        mAdapter.setAdjustSelectionBoundsEnabled(mAdjustSelectionBoundsEnabled);
779edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setIncludeProfile(mIncludeProfile);
780edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setQueryString(mQueryString);
781edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setDirectorySearchMode(mDirectorySearchMode);
78221826decea0b645be73f5e229a20632458360489Nancy Chen        mAdapter.setPinnedPartitionHeadersEnabled(false);
783edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setContactNameDisplayOrder(mDisplayOrder);
784edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setSortOrder(mSortOrder);
785edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setSectionHeaderDisplayEnabled(mSectionHeaderDisplayEnabled);
786edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setSelectionVisible(mSelectionVisible);
787edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setDirectoryResultLimit(mDirectoryResultLimit);
788edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mAdapter.setDarkTheme(mDarkTheme);
789edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
790edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
791edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
792edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
793edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            int totalItemCount) {
794edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
795edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
796edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
797edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onScrollStateChanged(AbsListView view, int scrollState) {
798edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
799edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mPhotoManager.pause();
800edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        } else if (isPhotoLoaderEnabled()) {
801edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mPhotoManager.resume();
802edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
803edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
804edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
805edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
806edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
807edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        hideSoftKeyboard();
808edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
809edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        int adjPosition = position - mListView.getHeaderViewsCount();
810edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (adjPosition >= 0) {
811edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            onItemClick(adjPosition, id);
812edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
813edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
814edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
815edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private void hideSoftKeyboard() {
816edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        // Hide soft keyboard, if visible
817edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        InputMethodManager inputMethodManager = (InputMethodManager)
818edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng                mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
819edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        inputMethodManager.hideSoftInputFromWindow(mListView.getWindowToken(), 0);
820edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
821edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
822edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
823edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Dismisses the soft keyboard when the list takes focus.
824edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
825edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
826edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onFocusChange(View view, boolean hasFocus) {
827edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (view == mListView && hasFocus) {
828edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            hideSoftKeyboard();
829edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
830edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
831edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
832edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
833edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Dismisses the soft keyboard when the list is touched.
834edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
835edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
836edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public boolean onTouch(View view, MotionEvent event) {
837edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (view == mListView) {
838edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            hideSoftKeyboard();
839edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
840edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        return false;
841edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
842edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
843edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    @Override
844edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onPause() {
845edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        super.onPause();
846edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        removePendingDirectorySearchRequests();
847edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
848edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
849edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
850edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Restore the list state after the adapter is populated.
851edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
852edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    protected void completeRestoreInstanceState() {
853edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mListState != null) {
854edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mListView.onRestoreInstanceState(mListState);
855edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            mListState = null;
856edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
857edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
858edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
859edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void setDarkTheme(boolean value) {
860edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        mDarkTheme = value;
861edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        if (mAdapter != null) mAdapter.setDarkTheme(value);
862edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
863edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
864edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    /**
865edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     * Processes a result returned by the contact picker.
866edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng     */
867edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    public void onPickerResult(Intent data) {
868edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        throw new UnsupportedOperationException("Picker result handler is not implemented.");
869edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    }
870edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng
871edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    private ContactsPreferences.ChangeListener mPreferencesChangeListener =
872edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            new ContactsPreferences.ChangeListener() {
873edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        @Override
874edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        public void onChange() {
875edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            loadPreferences();
876edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng            reloadData();
877edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng        }
878edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng    };
8799f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio
8809f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio    private int getDefaultVerticalScrollbarPosition() {
8819f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio        final Locale locale = Locale.getDefault();
8829f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio        final int layoutDirection = TextUtils.getLayoutDirectionFromLocale(locale);
8839f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio        switch (layoutDirection) {
8849f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio            case View.LAYOUT_DIRECTION_RTL:
8859f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio                return View.SCROLLBAR_POSITION_LEFT;
8869f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio            case View.LAYOUT_DIRECTION_LTR:
8879f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio            default:
8889f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio                return View.SCROLLBAR_POSITION_RIGHT;
8899f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio        }
8909f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio    }
891edc1cd98e3c3e991dcfb5281a008f7d2cfea1495Chiao Cheng}
892