Home | History | Annotate | Download | only in group
      1 /*
      2  * Copyright (C) 2011 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 
     17 package com.android.contacts.group;
     18 
     19 import android.app.Activity;
     20 import android.app.Fragment;
     21 import android.app.LoaderManager;
     22 import android.app.LoaderManager.LoaderCallbacks;
     23 import android.content.Context;
     24 import android.content.CursorLoader;
     25 import android.content.Intent;
     26 import android.content.Loader;
     27 import android.database.Cursor;
     28 import android.net.Uri;
     29 import android.os.Bundle;
     30 import android.provider.ContactsContract;
     31 import android.provider.Settings;
     32 import android.view.LayoutInflater;
     33 import android.view.MotionEvent;
     34 import android.view.View;
     35 import android.view.View.OnClickListener;
     36 import android.view.View.OnFocusChangeListener;
     37 import android.view.View.OnTouchListener;
     38 import android.view.ViewGroup;
     39 import android.view.inputmethod.InputMethodManager;
     40 import android.widget.AdapterView;
     41 import android.widget.AdapterView.OnItemClickListener;
     42 import android.widget.ListView;
     43 import android.widget.TextView;
     44 
     45 import com.android.contacts.GroupListLoader;
     46 import com.android.contacts.R;
     47 import com.android.contacts.group.GroupBrowseListAdapter.GroupListItemViewCache;
     48 import com.android.contacts.common.ContactsUtils;
     49 import com.android.contacts.common.list.AutoScrollListView;
     50 
     51 /**
     52  * Fragment to display the list of groups.
     53  */
     54 public class GroupBrowseListFragment extends Fragment
     55         implements OnFocusChangeListener, OnTouchListener {
     56 
     57     /**
     58      * Action callbacks that can be sent by a group list.
     59      */
     60     public interface OnGroupBrowserActionListener  {
     61 
     62         /**
     63          * Opens the specified group for viewing.
     64          *
     65          * @param groupUri for the group that the user wishes to view.
     66          */
     67         void onViewGroupAction(Uri groupUri);
     68 
     69     }
     70 
     71     private static final String TAG = "GroupBrowseListFragment";
     72 
     73     private static final int LOADER_GROUPS = 1;
     74 
     75     private Context mContext;
     76     private Cursor mGroupListCursor;
     77 
     78     private boolean mSelectionToScreenRequested;
     79 
     80     private static final String EXTRA_KEY_GROUP_URI = "groups.groupUri";
     81 
     82     private View mRootView;
     83     private AutoScrollListView mListView;
     84     private TextView mEmptyView;
     85     private View mAddAccountsView;
     86     private View mAddAccountButton;
     87 
     88     private GroupBrowseListAdapter mAdapter;
     89     private boolean mSelectionVisible;
     90     private Uri mSelectedGroupUri;
     91 
     92     private int mVerticalScrollbarPosition = View.SCROLLBAR_POSITION_RIGHT;
     93 
     94     private OnGroupBrowserActionListener mListener;
     95 
     96     public GroupBrowseListFragment() {
     97     }
     98 
     99     @Override
    100     public View onCreateView(LayoutInflater inflater, ViewGroup container,
    101             Bundle savedInstanceState) {
    102         if (savedInstanceState != null) {
    103             mSelectedGroupUri = savedInstanceState.getParcelable(EXTRA_KEY_GROUP_URI);
    104             if (mSelectedGroupUri != null) {
    105                 // The selection may be out of screen, if rotated from portrait to landscape,
    106                 // so ensure it's visible.
    107                 mSelectionToScreenRequested = true;
    108             }
    109         }
    110 
    111         mRootView = inflater.inflate(R.layout.group_browse_list_fragment, null);
    112         mEmptyView = (TextView)mRootView.findViewById(R.id.empty);
    113 
    114         mAdapter = new GroupBrowseListAdapter(mContext);
    115         mAdapter.setSelectionVisible(mSelectionVisible);
    116         mAdapter.setSelectedGroup(mSelectedGroupUri);
    117 
    118         mListView = (AutoScrollListView) mRootView.findViewById(R.id.list);
    119         mListView.setOnFocusChangeListener(this);
    120         mListView.setOnTouchListener(this);
    121         mListView.setAdapter(mAdapter);
    122         mListView.setOnItemClickListener(new OnItemClickListener() {
    123             @Override
    124             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    125                 GroupListItemViewCache groupListItem = (GroupListItemViewCache) view.getTag();
    126                 if (groupListItem != null) {
    127                     viewGroup(groupListItem.getUri());
    128                 }
    129             }
    130         });
    131 
    132         mListView.setEmptyView(mEmptyView);
    133         configureVerticalScrollbar();
    134 
    135         mAddAccountsView = mRootView.findViewById(R.id.add_accounts);
    136         mAddAccountButton = mRootView.findViewById(R.id.add_account_button);
    137         mAddAccountButton.setOnClickListener(new OnClickListener() {
    138             @Override
    139             public void onClick(View v) {
    140                 Intent intent = new Intent(Settings.ACTION_ADD_ACCOUNT);
    141                 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
    142                 intent.putExtra(Settings.EXTRA_AUTHORITIES,
    143                         new String[] { ContactsContract.AUTHORITY });
    144                 startActivity(intent);
    145             }
    146         });
    147         setAddAccountsVisibility(!ContactsUtils.areGroupWritableAccountsAvailable(mContext));
    148 
    149         return mRootView;
    150     }
    151 
    152     public void setVerticalScrollbarPosition(int position) {
    153         mVerticalScrollbarPosition = position;
    154         if (mListView != null) {
    155             configureVerticalScrollbar();
    156         }
    157     }
    158 
    159     private void configureVerticalScrollbar() {
    160         mListView.setVerticalScrollbarPosition(mVerticalScrollbarPosition);
    161         mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
    162         int leftPadding = 0;
    163         int rightPadding = 0;
    164         if (mVerticalScrollbarPosition == View.SCROLLBAR_POSITION_LEFT) {
    165             leftPadding = mContext.getResources().getDimensionPixelOffset(
    166                     R.dimen.list_visible_scrollbar_padding);
    167         } else {
    168             rightPadding = mContext.getResources().getDimensionPixelOffset(
    169                     R.dimen.list_visible_scrollbar_padding);
    170         }
    171         mListView.setPadding(leftPadding, mListView.getPaddingTop(),
    172                 rightPadding, mListView.getPaddingBottom());
    173     }
    174 
    175     @Override
    176     public void onAttach(Activity activity) {
    177         super.onAttach(activity);
    178         mContext = activity;
    179     }
    180 
    181     @Override
    182     public void onDetach() {
    183         super.onDetach();
    184         mContext = null;
    185     }
    186 
    187     @Override
    188     public void onStart() {
    189         getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupLoaderListener);
    190         super.onStart();
    191     }
    192 
    193     /**
    194      * The listener for the group meta data loader for all groups.
    195      */
    196     private final LoaderManager.LoaderCallbacks<Cursor> mGroupLoaderListener =
    197             new LoaderCallbacks<Cursor>() {
    198 
    199         @Override
    200         public CursorLoader onCreateLoader(int id, Bundle args) {
    201             mEmptyView.setText(null);
    202             return new GroupListLoader(mContext);
    203         }
    204 
    205         @Override
    206         public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    207             mGroupListCursor = data;
    208             bindGroupList();
    209         }
    210 
    211         public void onLoaderReset(Loader<Cursor> loader) {
    212         }
    213     };
    214 
    215     private void bindGroupList() {
    216         mEmptyView.setText(R.string.noGroups);
    217         setAddAccountsVisibility(!ContactsUtils.areGroupWritableAccountsAvailable(mContext));
    218         if (mGroupListCursor == null) {
    219             return;
    220         }
    221         mAdapter.setCursor(mGroupListCursor);
    222 
    223         if (mSelectionToScreenRequested) {
    224             mSelectionToScreenRequested = false;
    225             requestSelectionToScreen();
    226         }
    227 
    228         mSelectedGroupUri = mAdapter.getSelectedGroup();
    229         if (mSelectionVisible && mSelectedGroupUri != null) {
    230             viewGroup(mSelectedGroupUri);
    231         }
    232     }
    233 
    234     public void setListener(OnGroupBrowserActionListener listener) {
    235         mListener = listener;
    236     }
    237 
    238     public void setSelectionVisible(boolean flag) {
    239         mSelectionVisible = flag;
    240         if (mAdapter != null) {
    241             mAdapter.setSelectionVisible(mSelectionVisible);
    242         }
    243     }
    244 
    245     private void setSelectedGroup(Uri groupUri) {
    246         mSelectedGroupUri = groupUri;
    247         mAdapter.setSelectedGroup(groupUri);
    248         mListView.invalidateViews();
    249     }
    250 
    251     private void viewGroup(Uri groupUri) {
    252         setSelectedGroup(groupUri);
    253         if (mListener != null) mListener.onViewGroupAction(groupUri);
    254     }
    255 
    256     public void setSelectedUri(Uri groupUri) {
    257         viewGroup(groupUri);
    258         mSelectionToScreenRequested = true;
    259     }
    260 
    261     protected void requestSelectionToScreen() {
    262         if (!mSelectionVisible) {
    263             return; // If selection isn't visible we don't care.
    264         }
    265         int selectedPosition = mAdapter.getSelectedGroupPosition();
    266         if (selectedPosition != -1) {
    267             mListView.requestPositionToScreen(selectedPosition,
    268                     true /* smooth scroll requested */);
    269         }
    270     }
    271 
    272     private void hideSoftKeyboard() {
    273         if (mContext == null) {
    274             return;
    275         }
    276         // Hide soft keyboard, if visible
    277         InputMethodManager inputMethodManager = (InputMethodManager)
    278                 mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
    279         inputMethodManager.hideSoftInputFromWindow(mListView.getWindowToken(), 0);
    280     }
    281 
    282     /**
    283      * Dismisses the soft keyboard when the list takes focus.
    284      */
    285     @Override
    286     public void onFocusChange(View view, boolean hasFocus) {
    287         if (view == mListView && hasFocus) {
    288             hideSoftKeyboard();
    289         }
    290     }
    291 
    292     /**
    293      * Dismisses the soft keyboard when the list is touched.
    294      */
    295     @Override
    296     public boolean onTouch(View view, MotionEvent event) {
    297         if (view == mListView) {
    298             hideSoftKeyboard();
    299         }
    300         return false;
    301     }
    302 
    303     @Override
    304     public void onSaveInstanceState(Bundle outState) {
    305         super.onSaveInstanceState(outState);
    306         outState.putParcelable(EXTRA_KEY_GROUP_URI, mSelectedGroupUri);
    307     }
    308 
    309     public void setAddAccountsVisibility(boolean visible) {
    310         if (mAddAccountsView != null) {
    311             mAddAccountsView.setVisibility(visible ? View.VISIBLE : View.GONE);
    312         }
    313     }
    314 }
    315