1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.contacts.list; 17 18import android.content.Intent; 19import android.content.Loader; 20import android.database.Cursor; 21import android.net.Uri; 22import android.os.Bundle; 23import android.util.Log; 24import android.view.LayoutInflater; 25import android.view.MenuItem; 26import android.view.View; 27import android.view.View.OnClickListener; 28import android.view.ViewGroup; 29 30import com.android.contacts.R; 31import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener; 32import com.android.contacts.util.AccountFilterUtil; 33 34/** 35 * Fragment containing a phone number list for picking. 36 */ 37public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactEntryListAdapter> 38 implements OnShortcutIntentCreatedListener { 39 private static final String TAG = PhoneNumberPickerFragment.class.getSimpleName(); 40 41 private static final int REQUEST_CODE_ACCOUNT_FILTER = 1; 42 43 private static final String KEY_SHORTCUT_ACTION = "shortcutAction"; 44 45 private OnPhoneNumberPickerActionListener mListener; 46 private String mShortcutAction; 47 48 private ContactListFilter mFilter; 49 50 private View mAccountFilterHeader; 51 /** 52 * Lives as ListView's header and is shown when {@link #mAccountFilterHeader} is set 53 * to View.GONE. 54 */ 55 private View mPaddingView; 56 57 private static final String KEY_FILTER = "filter"; 58 59 /** true if the loader has started at least once. */ 60 private boolean mLoaderStarted; 61 62 private boolean mUseCallableUri; 63 64 private ContactListItemView.PhotoPosition mPhotoPosition = 65 ContactListItemView.DEFAULT_PHOTO_POSITION; 66 67 private class FilterHeaderClickListener implements OnClickListener { 68 @Override 69 public void onClick(View view) { 70 AccountFilterUtil.startAccountFilterActivityForResult( 71 PhoneNumberPickerFragment.this, 72 REQUEST_CODE_ACCOUNT_FILTER, 73 mFilter); 74 } 75 } 76 private OnClickListener mFilterHeaderClickListener = new FilterHeaderClickListener(); 77 78 public PhoneNumberPickerFragment() { 79 setQuickContactEnabled(false); 80 setPhotoLoaderEnabled(true); 81 setSectionHeaderDisplayEnabled(true); 82 setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DATA_SHORTCUT); 83 84 // Show nothing instead of letting caller Activity show something. 85 setHasOptionsMenu(true); 86 } 87 88 public void setOnPhoneNumberPickerActionListener(OnPhoneNumberPickerActionListener listener) { 89 this.mListener = listener; 90 } 91 92 @Override 93 protected void onCreateView(LayoutInflater inflater, ViewGroup container) { 94 super.onCreateView(inflater, container); 95 96 View paddingView = inflater.inflate(R.layout.contact_detail_list_padding, null, false); 97 mPaddingView = paddingView.findViewById(R.id.contact_detail_list_padding); 98 getListView().addHeaderView(paddingView); 99 100 mAccountFilterHeader = getView().findViewById(R.id.account_filter_header_container); 101 mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener); 102 updateFilterHeaderView(); 103 104 setVisibleScrollbarEnabled(!isLegacyCompatibilityMode()); 105 } 106 107 @Override 108 protected void setSearchMode(boolean flag) { 109 super.setSearchMode(flag); 110 updateFilterHeaderView(); 111 } 112 113 private void updateFilterHeaderView() { 114 final ContactListFilter filter = getFilter(); 115 if (mAccountFilterHeader == null || filter == null) { 116 return; 117 } 118 final boolean shouldShowHeader = 119 !isSearchMode() && 120 AccountFilterUtil.updateAccountFilterTitleForPhone( 121 mAccountFilterHeader, filter, false); 122 if (shouldShowHeader) { 123 mPaddingView.setVisibility(View.GONE); 124 mAccountFilterHeader.setVisibility(View.VISIBLE); 125 } else { 126 mPaddingView.setVisibility(View.VISIBLE); 127 mAccountFilterHeader.setVisibility(View.GONE); 128 } 129 } 130 131 @Override 132 public void restoreSavedState(Bundle savedState) { 133 super.restoreSavedState(savedState); 134 135 if (savedState == null) { 136 return; 137 } 138 139 mFilter = savedState.getParcelable(KEY_FILTER); 140 mShortcutAction = savedState.getString(KEY_SHORTCUT_ACTION); 141 } 142 143 @Override 144 public void onSaveInstanceState(Bundle outState) { 145 super.onSaveInstanceState(outState); 146 outState.putParcelable(KEY_FILTER, mFilter); 147 outState.putString(KEY_SHORTCUT_ACTION, mShortcutAction); 148 } 149 150 @Override 151 public boolean onOptionsItemSelected(MenuItem item) { 152 final int itemId = item.getItemId(); 153 if (itemId == android.R.id.home) { // See ActionBar#setDisplayHomeAsUpEnabled() 154 if (mListener != null) { 155 mListener.onHomeInActionBarSelected(); 156 } 157 return true; 158 } 159 return super.onOptionsItemSelected(item); 160 } 161 162 /** 163 * @param shortcutAction either {@link Intent#ACTION_CALL} or 164 * {@link Intent#ACTION_SENDTO} or null. 165 */ 166 public void setShortcutAction(String shortcutAction) { 167 this.mShortcutAction = shortcutAction; 168 } 169 170 @Override 171 protected void onItemClick(int position, long id) { 172 final Uri phoneUri; 173 if (!isLegacyCompatibilityMode()) { 174 PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter(); 175 phoneUri = adapter.getDataUri(position); 176 177 } else { 178 LegacyPhoneNumberListAdapter adapter = (LegacyPhoneNumberListAdapter) getAdapter(); 179 phoneUri = adapter.getPhoneUri(position); 180 } 181 182 if (phoneUri != null) { 183 pickPhoneNumber(phoneUri); 184 } else { 185 Log.w(TAG, "Item at " + position + " was clicked before adapter is ready. Ignoring"); 186 } 187 } 188 189 @Override 190 protected void startLoading() { 191 mLoaderStarted = true; 192 super.startLoading(); 193 } 194 195 @Override 196 public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 197 super.onLoadFinished(loader, data); 198 199 // disable scroll bar if there is no data 200 setVisibleScrollbarEnabled(data.getCount() > 0); 201 } 202 203 public void setUseCallableUri(boolean useCallableUri) { 204 mUseCallableUri = useCallableUri; 205 } 206 207 public boolean usesCallableUri() { 208 return mUseCallableUri; 209 } 210 211 @Override 212 protected ContactEntryListAdapter createListAdapter() { 213 if (!isLegacyCompatibilityMode()) { 214 PhoneNumberListAdapter adapter = new PhoneNumberListAdapter(getActivity()); 215 adapter.setDisplayPhotos(true); 216 adapter.setUseCallableUri(mUseCallableUri); 217 return adapter; 218 } else { 219 LegacyPhoneNumberListAdapter adapter = new LegacyPhoneNumberListAdapter(getActivity()); 220 adapter.setDisplayPhotos(true); 221 return adapter; 222 } 223 } 224 225 @Override 226 protected void configureAdapter() { 227 super.configureAdapter(); 228 229 final ContactEntryListAdapter adapter = getAdapter(); 230 if (adapter == null) { 231 return; 232 } 233 234 if (!isSearchMode() && mFilter != null) { 235 adapter.setFilter(mFilter); 236 } 237 238 if (!isLegacyCompatibilityMode()) { 239 ((PhoneNumberListAdapter) adapter).setPhotoPosition(mPhotoPosition); 240 } 241 } 242 243 @Override 244 protected View inflateView(LayoutInflater inflater, ViewGroup container) { 245 return inflater.inflate(R.layout.contact_list_content, null); 246 } 247 248 public void pickPhoneNumber(Uri uri) { 249 if (mShortcutAction == null) { 250 mListener.onPickPhoneNumberAction(uri); 251 } else { 252 if (isLegacyCompatibilityMode()) { 253 throw new UnsupportedOperationException(); 254 } 255 ShortcutIntentBuilder builder = new ShortcutIntentBuilder(getActivity(), this); 256 builder.createPhoneNumberShortcutIntent(uri, mShortcutAction); 257 } 258 } 259 260 public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) { 261 mListener.onShortcutIntentCreated(shortcutIntent); 262 } 263 264 @Override 265 public void onPickerResult(Intent data) { 266 mListener.onPickPhoneNumberAction(data.getData()); 267 } 268 269 @Override 270 public void onActivityResult(int requestCode, int resultCode, Intent data) { 271 if (requestCode == REQUEST_CODE_ACCOUNT_FILTER) { 272 if (getActivity() != null) { 273 AccountFilterUtil.handleAccountFilterResult( 274 ContactListFilterController.getInstance(getActivity()), resultCode, data); 275 } else { 276 Log.e(TAG, "getActivity() returns null during Fragment#onActivityResult()"); 277 } 278 } 279 } 280 281 public ContactListFilter getFilter() { 282 return mFilter; 283 } 284 285 public void setFilter(ContactListFilter filter) { 286 if ((mFilter == null && filter == null) || 287 (mFilter != null && mFilter.equals(filter))) { 288 return; 289 } 290 291 mFilter = filter; 292 if (mLoaderStarted) { 293 reloadData(); 294 } 295 updateFilterHeaderView(); 296 } 297 298 public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) { 299 mPhotoPosition = photoPosition; 300 if (!isLegacyCompatibilityMode()) { 301 final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter(); 302 if (adapter != null) { 303 adapter.setPhotoPosition(photoPosition); 304 } 305 } else { 306 Log.w(TAG, "setPhotoPosition() is ignored in legacy compatibility mode."); 307 } 308 } 309} 310