Home | History | Annotate | Download | only in list
      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.text.TextUtils;
     24 import android.util.Log;
     25 import android.view.LayoutInflater;
     26 import android.view.MenuItem;
     27 import android.view.View;
     28 import android.view.View.OnClickListener;
     29 import android.view.ViewGroup;
     30 
     31 import com.android.contacts.common.R;
     32 import com.android.contacts.common.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
     33 import com.android.contacts.common.util.AccountFilterUtil;
     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.getDefaultPhotoPosition(false /* normal/non opposite */);
     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_NONE);
     84 
     85         // Show nothing instead of letting caller Activity show something.
     86         setHasOptionsMenu(true);
     87     }
     88 
     89     public void setDirectorySearchEnabled(boolean flag) {
     90         setDirectorySearchMode(flag ? DirectoryListLoader.SEARCH_MODE_DEFAULT
     91                 : DirectoryListLoader.SEARCH_MODE_NONE);
     92     }
     93 
     94     public void setOnPhoneNumberPickerActionListener(OnPhoneNumberPickerActionListener listener) {
     95         this.mListener = listener;
     96     }
     97 
     98     public OnPhoneNumberPickerActionListener getOnPhoneNumberPickerListener() {
     99         return mListener;
    100     }
    101 
    102     @Override
    103     protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
    104         super.onCreateView(inflater, container);
    105 
    106         View paddingView = inflater.inflate(R.layout.contact_detail_list_padding, null, false);
    107         mPaddingView = paddingView.findViewById(R.id.contact_detail_list_padding);
    108         getListView().addHeaderView(paddingView);
    109 
    110         mAccountFilterHeader = getView().findViewById(R.id.account_filter_header_container);
    111         mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener);
    112         updateFilterHeaderView();
    113 
    114         setVisibleScrollbarEnabled(getVisibleScrollbarEnabled());
    115     }
    116 
    117     protected boolean getVisibleScrollbarEnabled() {
    118         return true;
    119     }
    120 
    121     @Override
    122     protected void setSearchMode(boolean flag) {
    123         super.setSearchMode(flag);
    124         updateFilterHeaderView();
    125     }
    126 
    127     private void updateFilterHeaderView() {
    128         final ContactListFilter filter = getFilter();
    129         if (mAccountFilterHeader == null || filter == null) {
    130             return;
    131         }
    132         final boolean shouldShowHeader =
    133                 !isSearchMode() &&
    134                 AccountFilterUtil.updateAccountFilterTitleForPhone(
    135                         mAccountFilterHeader, filter, false);
    136         if (shouldShowHeader) {
    137             mPaddingView.setVisibility(View.GONE);
    138             mAccountFilterHeader.setVisibility(View.VISIBLE);
    139         } else {
    140             mPaddingView.setVisibility(View.VISIBLE);
    141             mAccountFilterHeader.setVisibility(View.GONE);
    142         }
    143     }
    144 
    145     @Override
    146     public void restoreSavedState(Bundle savedState) {
    147         super.restoreSavedState(savedState);
    148 
    149         if (savedState == null) {
    150             return;
    151         }
    152 
    153         mFilter = savedState.getParcelable(KEY_FILTER);
    154         mShortcutAction = savedState.getString(KEY_SHORTCUT_ACTION);
    155     }
    156 
    157     @Override
    158     public void onSaveInstanceState(Bundle outState) {
    159         super.onSaveInstanceState(outState);
    160         outState.putParcelable(KEY_FILTER, mFilter);
    161         outState.putString(KEY_SHORTCUT_ACTION, mShortcutAction);
    162     }
    163 
    164     @Override
    165     public boolean onOptionsItemSelected(MenuItem item) {
    166         final int itemId = item.getItemId();
    167         if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
    168             if (mListener != null) {
    169                 mListener.onHomeInActionBarSelected();
    170             }
    171             return true;
    172         }
    173         return super.onOptionsItemSelected(item);
    174     }
    175 
    176     /**
    177      * @param shortcutAction either {@link Intent#ACTION_CALL} or
    178      *            {@link Intent#ACTION_SENDTO} or null.
    179      */
    180     public void setShortcutAction(String shortcutAction) {
    181         this.mShortcutAction = shortcutAction;
    182     }
    183 
    184     @Override
    185     protected void onItemClick(int position, long id) {
    186         final Uri phoneUri = getPhoneUri(position);
    187 
    188         if (phoneUri != null) {
    189             pickPhoneNumber(phoneUri);
    190         } else {
    191             final String number = getPhoneNumber(position);
    192             if (!TextUtils.isEmpty(number)) {
    193                 cacheContactInfo(position);
    194                 mListener.onCallNumberDirectly(number);
    195             } else {
    196                 Log.w(TAG, "Item at " + position + " was clicked before"
    197                         + " adapter is ready. Ignoring");
    198             }
    199         }
    200     }
    201 
    202     protected void cacheContactInfo(int position) {
    203         // Not implemented. Hook for child classes
    204     }
    205 
    206     protected String getPhoneNumber(int position) {
    207         final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
    208         return adapter.getPhoneNumber(position);
    209     }
    210 
    211     protected Uri getPhoneUri(int position) {
    212         final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
    213         return adapter.getDataUri(position);
    214     }
    215 
    216     @Override
    217     protected void startLoading() {
    218         mLoaderStarted = true;
    219         super.startLoading();
    220     }
    221 
    222     @Override
    223     public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    224         super.onLoadFinished(loader, data);
    225 
    226         // disable scroll bar if there is no data
    227         setVisibleScrollbarEnabled(data != null && data.getCount() > 0);
    228     }
    229 
    230     public void setUseCallableUri(boolean useCallableUri) {
    231         mUseCallableUri = useCallableUri;
    232     }
    233 
    234     public boolean usesCallableUri() {
    235         return mUseCallableUri;
    236     }
    237 
    238     @Override
    239     protected ContactEntryListAdapter createListAdapter() {
    240         PhoneNumberListAdapter adapter = new PhoneNumberListAdapter(getActivity());
    241         adapter.setDisplayPhotos(true);
    242         adapter.setUseCallableUri(mUseCallableUri);
    243         return adapter;
    244     }
    245 
    246     @Override
    247     protected void configureAdapter() {
    248         super.configureAdapter();
    249 
    250         final ContactEntryListAdapter adapter = getAdapter();
    251         if (adapter == null) {
    252             return;
    253         }
    254 
    255         if (!isSearchMode() && mFilter != null) {
    256             adapter.setFilter(mFilter);
    257         }
    258 
    259         setPhotoPosition(adapter);
    260     }
    261 
    262     protected void setPhotoPosition(ContactEntryListAdapter adapter) {
    263         ((PhoneNumberListAdapter) adapter).setPhotoPosition(mPhotoPosition);
    264     }
    265 
    266     @Override
    267     protected View inflateView(LayoutInflater inflater, ViewGroup container) {
    268         return inflater.inflate(R.layout.contact_list_content, null);
    269     }
    270 
    271     public void pickPhoneNumber(Uri uri) {
    272         if (mShortcutAction == null) {
    273             mListener.onPickPhoneNumberAction(uri);
    274         } else {
    275             startPhoneNumberShortcutIntent(uri);
    276         }
    277     }
    278 
    279     protected void startPhoneNumberShortcutIntent(Uri uri) {
    280         ShortcutIntentBuilder builder = new ShortcutIntentBuilder(getActivity(), this);
    281         builder.createPhoneNumberShortcutIntent(uri, mShortcutAction);
    282     }
    283 
    284     public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
    285         mListener.onShortcutIntentCreated(shortcutIntent);
    286     }
    287 
    288     @Override
    289     public void onPickerResult(Intent data) {
    290         mListener.onPickPhoneNumberAction(data.getData());
    291     }
    292 
    293     @Override
    294     public void onActivityResult(int requestCode, int resultCode, Intent data) {
    295         if (requestCode == REQUEST_CODE_ACCOUNT_FILTER) {
    296             if (getActivity() != null) {
    297                 AccountFilterUtil.handleAccountFilterResult(
    298                         ContactListFilterController.getInstance(getActivity()), resultCode, data);
    299             } else {
    300                 Log.e(TAG, "getActivity() returns null during Fragment#onActivityResult()");
    301             }
    302         }
    303     }
    304 
    305     public ContactListFilter getFilter() {
    306         return mFilter;
    307     }
    308 
    309     public void setFilter(ContactListFilter filter) {
    310         if ((mFilter == null && filter == null) ||
    311                 (mFilter != null && mFilter.equals(filter))) {
    312             return;
    313         }
    314 
    315         mFilter = filter;
    316         if (mLoaderStarted) {
    317             reloadData();
    318         }
    319         updateFilterHeaderView();
    320     }
    321 
    322     public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) {
    323         mPhotoPosition = photoPosition;
    324 
    325         final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
    326         if (adapter != null) {
    327             adapter.setPhotoPosition(photoPosition);
    328         }
    329     }
    330 }
    331