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.common.list; 17 18 import android.content.Intent; 19 import android.content.Loader; 20 import android.database.Cursor; 21 import android.net.Uri; 22 import android.os.Bundle; 23 import android.util.Log; 24 import android.view.LayoutInflater; 25 import android.view.MenuItem; 26 import android.view.View; 27 import android.view.View.OnClickListener; 28 import android.view.ViewGroup; 29 30 import com.android.contacts.common.R; 31 import com.android.contacts.common.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener; 32 import com.android.contacts.common.util.AccountFilterUtil; 33 34 /** 35 * Fragment containing a phone number list for picking. 36 */ 37 public 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.getDefaultPhotoPosition(false /* normal/non opposite */); 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(getVisibleScrollbarEnabled()); 105 } 106 107 protected boolean getVisibleScrollbarEnabled() { 108 return true; 109 } 110 111 @Override 112 protected void setSearchMode(boolean flag) { 113 super.setSearchMode(flag); 114 updateFilterHeaderView(); 115 } 116 117 private void updateFilterHeaderView() { 118 final ContactListFilter filter = getFilter(); 119 if (mAccountFilterHeader == null || filter == null) { 120 return; 121 } 122 final boolean shouldShowHeader = 123 !isSearchMode() && 124 AccountFilterUtil.updateAccountFilterTitleForPhone( 125 mAccountFilterHeader, filter, false); 126 if (shouldShowHeader) { 127 mPaddingView.setVisibility(View.GONE); 128 mAccountFilterHeader.setVisibility(View.VISIBLE); 129 } else { 130 mPaddingView.setVisibility(View.VISIBLE); 131 mAccountFilterHeader.setVisibility(View.GONE); 132 } 133 } 134 135 @Override 136 public void restoreSavedState(Bundle savedState) { 137 super.restoreSavedState(savedState); 138 139 if (savedState == null) { 140 return; 141 } 142 143 mFilter = savedState.getParcelable(KEY_FILTER); 144 mShortcutAction = savedState.getString(KEY_SHORTCUT_ACTION); 145 } 146 147 @Override 148 public void onSaveInstanceState(Bundle outState) { 149 super.onSaveInstanceState(outState); 150 outState.putParcelable(KEY_FILTER, mFilter); 151 outState.putString(KEY_SHORTCUT_ACTION, mShortcutAction); 152 } 153 154 @Override 155 public boolean onOptionsItemSelected(MenuItem item) { 156 final int itemId = item.getItemId(); 157 if (itemId == android.R.id.home) { // See ActionBar#setDisplayHomeAsUpEnabled() 158 if (mListener != null) { 159 mListener.onHomeInActionBarSelected(); 160 } 161 return true; 162 } 163 return super.onOptionsItemSelected(item); 164 } 165 166 /** 167 * @param shortcutAction either {@link Intent#ACTION_CALL} or 168 * {@link Intent#ACTION_SENDTO} or null. 169 */ 170 public void setShortcutAction(String shortcutAction) { 171 this.mShortcutAction = shortcutAction; 172 } 173 174 @Override 175 protected void onItemClick(int position, long id) { 176 final Uri phoneUri = getPhoneUri(position); 177 178 if (phoneUri != null) { 179 pickPhoneNumber(phoneUri); 180 } else { 181 Log.w(TAG, "Item at " + position + " was clicked before adapter is ready. Ignoring"); 182 } 183 } 184 185 protected Uri getPhoneUri(int position) { 186 final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter(); 187 return adapter.getDataUri(position); 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 PhoneNumberListAdapter adapter = new PhoneNumberListAdapter(getActivity()); 215 adapter.setDisplayPhotos(true); 216 adapter.setUseCallableUri(mUseCallableUri); 217 return adapter; 218 } 219 220 @Override 221 protected void configureAdapter() { 222 super.configureAdapter(); 223 224 final ContactEntryListAdapter adapter = getAdapter(); 225 if (adapter == null) { 226 return; 227 } 228 229 if (!isSearchMode() && mFilter != null) { 230 adapter.setFilter(mFilter); 231 } 232 233 setPhotoPosition(adapter); 234 } 235 236 protected void setPhotoPosition(ContactEntryListAdapter adapter) { 237 ((PhoneNumberListAdapter) adapter).setPhotoPosition(mPhotoPosition); 238 } 239 240 @Override 241 protected View inflateView(LayoutInflater inflater, ViewGroup container) { 242 return inflater.inflate(R.layout.contact_list_content, null); 243 } 244 245 public void pickPhoneNumber(Uri uri) { 246 if (mShortcutAction == null) { 247 mListener.onPickPhoneNumberAction(uri); 248 } else { 249 startPhoneNumberShortcutIntent(uri); 250 } 251 } 252 253 protected void startPhoneNumberShortcutIntent(Uri uri) { 254 ShortcutIntentBuilder builder = new ShortcutIntentBuilder(getActivity(), this); 255 builder.createPhoneNumberShortcutIntent(uri, mShortcutAction); 256 } 257 258 public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) { 259 mListener.onShortcutIntentCreated(shortcutIntent); 260 } 261 262 @Override 263 public void onPickerResult(Intent data) { 264 mListener.onPickPhoneNumberAction(data.getData()); 265 } 266 267 @Override 268 public void onActivityResult(int requestCode, int resultCode, Intent data) { 269 if (requestCode == REQUEST_CODE_ACCOUNT_FILTER) { 270 if (getActivity() != null) { 271 AccountFilterUtil.handleAccountFilterResult( 272 ContactListFilterController.getInstance(getActivity()), resultCode, data); 273 } else { 274 Log.e(TAG, "getActivity() returns null during Fragment#onActivityResult()"); 275 } 276 } 277 } 278 279 public ContactListFilter getFilter() { 280 return mFilter; 281 } 282 283 public void setFilter(ContactListFilter filter) { 284 if ((mFilter == null && filter == null) || 285 (mFilter != null && mFilter.equals(filter))) { 286 return; 287 } 288 289 mFilter = filter; 290 if (mLoaderStarted) { 291 reloadData(); 292 } 293 updateFilterHeaderView(); 294 } 295 296 public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) { 297 mPhotoPosition = photoPosition; 298 299 final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter(); 300 if (adapter != null) { 301 adapter.setPhotoPosition(photoPosition); 302 } 303 } 304 } 305