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.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