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