19add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan/*
29add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan * Copyright (C) 2011 The Android Open Source Project
39add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan *
49add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan * Licensed under the Apache License, Version 2.0 (the "License");
59add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan * you may not use this file except in compliance with the License.
69add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan * You may obtain a copy of the License at
79add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan *
89add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan *      http://www.apache.org/licenses/LICENSE-2.0
99add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan *
109add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan * Unless required by applicable law or agreed to in writing, software
119add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan * distributed under the License is distributed on an "AS IS" BASIS,
129add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan * See the License for the specific language governing permissions and
149add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan * limitations under the License.
159add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan */
169add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
179add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanpackage com.android.contacts.group;
189add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
199add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.app.Activity;
209add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.app.Fragment;
219add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.app.LoaderManager;
229add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.app.LoaderManager.LoaderCallbacks;
239add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.content.Context;
249add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.content.CursorLoader;
2566606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelsonimport android.content.Intent;
269add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.content.Loader;
279add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.database.Cursor;
28be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuanimport android.net.Uri;
299add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.os.Bundle;
3066606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelsonimport android.provider.ContactsContract;
3166606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelsonimport android.provider.Settings;
329add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.view.LayoutInflater;
339add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.view.MotionEvent;
349add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.view.View;
3566606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelsonimport android.view.View.OnClickListener;
369add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.view.View.OnFocusChangeListener;
379add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.view.View.OnTouchListener;
389add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.view.ViewGroup;
399add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.view.inputmethod.InputMethodManager;
40fd8cdedb816cb1fc5894e2e3c5e144ff16b90b7cKatherine Kuanimport android.widget.AdapterView;
41fd8cdedb816cb1fc5894e2e3c5e144ff16b90b7cKatherine Kuanimport android.widget.AdapterView.OnItemClickListener;
429add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanimport android.widget.ListView;
43a1bbf6139bb1e0d30078fe6c99effaf45f7416efIsaac Katzenelsonimport android.widget.TextView;
449add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
45e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.GroupListLoader;
46e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R;
47e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.group.GroupBrowseListAdapter.GroupListItemViewCache;
48cd321f65f1e50409812976380ad1f0fdb3fa35cbYorke Leeimport com.android.contacts.common.ContactsUtils;
49a0233a048858f1593ea4924e9c5036f39aedbcddChiao Chengimport com.android.contacts.common.list.AutoScrollListView;
50e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng
519add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan/**
529add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan * Fragment to display the list of groups.
539add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan */
549add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuanpublic class GroupBrowseListFragment extends Fragment
559add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        implements OnFocusChangeListener, OnTouchListener {
569add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
57be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan    /**
58be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan     * Action callbacks that can be sent by a group list.
59be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan     */
60be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan    public interface OnGroupBrowserActionListener  {
61be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan
62be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan        /**
63be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan         * Opens the specified group for viewing.
64be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan         *
65be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan         * @param groupUri for the group that the user wishes to view.
66be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan         */
67be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan        void onViewGroupAction(Uri groupUri);
6866606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson
69be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan    }
70be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan
719add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    private static final String TAG = "GroupBrowseListFragment";
729add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
739add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    private static final int LOADER_GROUPS = 1;
749add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
759add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    private Context mContext;
769add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    private Cursor mGroupListCursor;
770ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan
78c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan    private boolean mSelectionToScreenRequested;
79c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan
8059dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson    private static final String EXTRA_KEY_GROUP_URI = "groups.groupUri";
8159dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson
829add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    private View mRootView;
83c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan    private AutoScrollListView mListView;
84a1bbf6139bb1e0d30078fe6c99effaf45f7416efIsaac Katzenelson    private TextView mEmptyView;
8566606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson    private View mAddAccountsView;
8666606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson    private View mAddAccountButton;
879add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
880ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    private GroupBrowseListAdapter mAdapter;
890ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    private boolean mSelectionVisible;
90c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan    private Uri mSelectedGroupUri;
910ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan
920ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    private int mVerticalScrollbarPosition = View.SCROLLBAR_POSITION_RIGHT;
930ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan
94be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan    private OnGroupBrowserActionListener mListener;
95be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan
969add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    public GroupBrowseListFragment() {
979add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    }
989add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
999add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    @Override
1009add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    public View onCreateView(LayoutInflater inflater, ViewGroup container,
1019add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan            Bundle savedInstanceState) {
1024715cafcbe76ac79b0b25ec62ec4ad8b55a2d41dMakoto Onuki        if (savedInstanceState != null) {
1034715cafcbe76ac79b0b25ec62ec4ad8b55a2d41dMakoto Onuki            mSelectedGroupUri = savedInstanceState.getParcelable(EXTRA_KEY_GROUP_URI);
1044715cafcbe76ac79b0b25ec62ec4ad8b55a2d41dMakoto Onuki            if (mSelectedGroupUri != null) {
1054715cafcbe76ac79b0b25ec62ec4ad8b55a2d41dMakoto Onuki                // The selection may be out of screen, if rotated from portrait to landscape,
1064715cafcbe76ac79b0b25ec62ec4ad8b55a2d41dMakoto Onuki                // so ensure it's visible.
1074715cafcbe76ac79b0b25ec62ec4ad8b55a2d41dMakoto Onuki                mSelectionToScreenRequested = true;
1084715cafcbe76ac79b0b25ec62ec4ad8b55a2d41dMakoto Onuki            }
1094715cafcbe76ac79b0b25ec62ec4ad8b55a2d41dMakoto Onuki        }
1104715cafcbe76ac79b0b25ec62ec4ad8b55a2d41dMakoto Onuki
1119add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        mRootView = inflater.inflate(R.layout.group_browse_list_fragment, null);
112a1bbf6139bb1e0d30078fe6c99effaf45f7416efIsaac Katzenelson        mEmptyView = (TextView)mRootView.findViewById(R.id.empty);
113ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan
114ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan        mAdapter = new GroupBrowseListAdapter(mContext);
115ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan        mAdapter.setSelectionVisible(mSelectionVisible);
116ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan        mAdapter.setSelectedGroup(mSelectedGroupUri);
117ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan
118c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan        mListView = (AutoScrollListView) mRootView.findViewById(R.id.list);
1199add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        mListView.setOnFocusChangeListener(this);
1209add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        mListView.setOnTouchListener(this);
121ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan        mListView.setAdapter(mAdapter);
122ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan        mListView.setOnItemClickListener(new OnItemClickListener() {
123ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan            @Override
124ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
125ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan                GroupListItemViewCache groupListItem = (GroupListItemViewCache) view.getTag();
126ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan                if (groupListItem != null) {
127ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan                    viewGroup(groupListItem.getUri());
128ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan                }
129ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan            }
130ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan        });
13159dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson
132a1bbf6139bb1e0d30078fe6c99effaf45f7416efIsaac Katzenelson        mListView.setEmptyView(mEmptyView);
133f7bd441e39232a9953f707cf1e9c7253108b8865Chiao Cheng        configureVerticalScrollbar();
134f7bd441e39232a9953f707cf1e9c7253108b8865Chiao Cheng
13566606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson        mAddAccountsView = mRootView.findViewById(R.id.add_accounts);
13666606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson        mAddAccountButton = mRootView.findViewById(R.id.add_account_button);
13766606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson        mAddAccountButton.setOnClickListener(new OnClickListener() {
13866606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson            @Override
13966606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson            public void onClick(View v) {
14066606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson                Intent intent = new Intent(Settings.ACTION_ADD_ACCOUNT);
14166606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
14266606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson                intent.putExtra(Settings.EXTRA_AUTHORITIES,
14366606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson                        new String[] { ContactsContract.AUTHORITY });
14466606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson                startActivity(intent);
14566606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson            }
14666606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson        });
1476f74c0f3313cbb08ee8a8fbb79bfefc5b03fe215Makoto Onuki        setAddAccountsVisibility(!ContactsUtils.areGroupWritableAccountsAvailable(mContext));
14866606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson
1499add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        return mRootView;
1509add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    }
1519add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
1520ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    public void setVerticalScrollbarPosition(int position) {
153e90783822d17ef7696d8ec09ebb3ddd6d1768986Chiao Cheng        mVerticalScrollbarPosition = position;
154f7bd441e39232a9953f707cf1e9c7253108b8865Chiao Cheng        if (mListView != null) {
155f7bd441e39232a9953f707cf1e9c7253108b8865Chiao Cheng            configureVerticalScrollbar();
156f7bd441e39232a9953f707cf1e9c7253108b8865Chiao Cheng        }
1570ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    }
1580ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan
1590ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    private void configureVerticalScrollbar() {
1600ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        mListView.setVerticalScrollbarPosition(mVerticalScrollbarPosition);
1610ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
1620ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        int leftPadding = 0;
1630ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        int rightPadding = 0;
1640ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        if (mVerticalScrollbarPosition == View.SCROLLBAR_POSITION_LEFT) {
1650ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan            leftPadding = mContext.getResources().getDimensionPixelOffset(
1660ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan                    R.dimen.list_visible_scrollbar_padding);
1670ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        } else {
1680ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan            rightPadding = mContext.getResources().getDimensionPixelOffset(
1690ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan                    R.dimen.list_visible_scrollbar_padding);
1700ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        }
1710ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        mListView.setPadding(leftPadding, mListView.getPaddingTop(),
1720ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan                rightPadding, mListView.getPaddingBottom());
1730ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    }
1740ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan
1759add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    @Override
1769add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    public void onAttach(Activity activity) {
1779add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        super.onAttach(activity);
1789add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        mContext = activity;
1799add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    }
1809add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
1819add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    @Override
1829add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    public void onDetach() {
1839add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        super.onDetach();
1849add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        mContext = null;
1859add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    }
1869add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
1879add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    @Override
1889add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    public void onStart() {
1899add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupLoaderListener);
1909add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        super.onStart();
1919add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    }
1929add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
1939add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    /**
194be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan     * The listener for the group meta data loader for all groups.
1959add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan     */
1969add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    private final LoaderManager.LoaderCallbacks<Cursor> mGroupLoaderListener =
1979add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan            new LoaderCallbacks<Cursor>() {
1989add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
1999add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        @Override
2009add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        public CursorLoader onCreateLoader(int id, Bundle args) {
201a1bbf6139bb1e0d30078fe6c99effaf45f7416efIsaac Katzenelson            mEmptyView.setText(null);
202ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan            return new GroupListLoader(mContext);
2039add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        }
2049add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
2059add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        @Override
2069add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
2079add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan            mGroupListCursor = data;
2089add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan            bindGroupList();
2099add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        }
2109add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
2119add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        public void onLoaderReset(Loader<Cursor> loader) {
2129add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        }
2139add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    };
2149add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
2159add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    private void bindGroupList() {
216a1bbf6139bb1e0d30078fe6c99effaf45f7416efIsaac Katzenelson        mEmptyView.setText(R.string.noGroups);
2176f74c0f3313cbb08ee8a8fbb79bfefc5b03fe215Makoto Onuki        setAddAccountsVisibility(!ContactsUtils.areGroupWritableAccountsAvailable(mContext));
2189add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        if (mGroupListCursor == null) {
2199add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan            return;
2209add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        }
221ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan        mAdapter.setCursor(mGroupListCursor);
2220ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan
223c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan        if (mSelectionToScreenRequested) {
22444b90b09a61c53cd61b6f8ff0889f85b7d3490bbMakoto Onuki            mSelectionToScreenRequested = false;
225c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan            requestSelectionToScreen();
226c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan        }
22759dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson
228cab054c6d3336ef54dd60ed208df490fae6566dbKatherine Kuan        mSelectedGroupUri = mAdapter.getSelectedGroup();
22959dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson        if (mSelectionVisible && mSelectedGroupUri != null) {
23059dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson            viewGroup(mSelectedGroupUri);
23159dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson        }
232fd8cdedb816cb1fc5894e2e3c5e144ff16b90b7cKatherine Kuan    }
233fd8cdedb816cb1fc5894e2e3c5e144ff16b90b7cKatherine Kuan
234be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan    public void setListener(OnGroupBrowserActionListener listener) {
235be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan        mListener = listener;
236be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan    }
237be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan
2380ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    public void setSelectionVisible(boolean flag) {
2390ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        mSelectionVisible = flag;
240ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan        if (mAdapter != null) {
241ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan            mAdapter.setSelectionVisible(mSelectionVisible);
242ea1c3a50874de0e1c34df7a3bd650fb64538f04dKatherine Kuan        }
2430ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    }
2440ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan
2450ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    private void setSelectedGroup(Uri groupUri) {
246c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan        mSelectedGroupUri = groupUri;
2470ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        mAdapter.setSelectedGroup(groupUri);
2480ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        mListView.invalidateViews();
2490ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan    }
2500ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan
251be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan    private void viewGroup(Uri groupUri) {
2520ff0e317cbf788adc4dce38257d27691e032d6caKatherine Kuan        setSelectedGroup(groupUri);
253be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan        if (mListener != null) mListener.onViewGroupAction(groupUri);
2549add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    }
2559add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
256c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan    public void setSelectedUri(Uri groupUri) {
257c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan        viewGroup(groupUri);
258c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan        mSelectionToScreenRequested = true;
259c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan    }
260c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan
261c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan    protected void requestSelectionToScreen() {
26244b90b09a61c53cd61b6f8ff0889f85b7d3490bbMakoto Onuki        if (!mSelectionVisible) {
26344b90b09a61c53cd61b6f8ff0889f85b7d3490bbMakoto Onuki            return; // If selection isn't visible we don't care.
26444b90b09a61c53cd61b6f8ff0889f85b7d3490bbMakoto Onuki        }
265c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan        int selectedPosition = mAdapter.getSelectedGroupPosition();
266c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan        if (selectedPosition != -1) {
26708c87460331cbab92e94d96b704bd8f713a65202Daisuke Miyakawa            mListView.requestPositionToScreen(selectedPosition,
26808c87460331cbab92e94d96b704bd8f713a65202Daisuke Miyakawa                    true /* smooth scroll requested */);
269c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan        }
270c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan    }
271c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan
2729add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    private void hideSoftKeyboard() {
2739add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        if (mContext == null) {
2749add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan            return;
2759add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        }
2769add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        // Hide soft keyboard, if visible
2779add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        InputMethodManager inputMethodManager = (InputMethodManager)
2789add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan                mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
2799add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        inputMethodManager.hideSoftInputFromWindow(mListView.getWindowToken(), 0);
2809add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    }
2819add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
2829add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    /**
2839add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan     * Dismisses the soft keyboard when the list takes focus.
2849add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan     */
2859add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    @Override
2869add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    public void onFocusChange(View view, boolean hasFocus) {
2879add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        if (view == mListView && hasFocus) {
2889add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan            hideSoftKeyboard();
2899add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        }
2909add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    }
2919add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
2929add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    /**
2939add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan     * Dismisses the soft keyboard when the list is touched.
2949add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan     */
2959add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    @Override
2969add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    public boolean onTouch(View view, MotionEvent event) {
2979add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        if (view == mListView) {
2989add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan            hideSoftKeyboard();
2999add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        }
3009add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan        return false;
3019add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    }
30259dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson
30359dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson    @Override
30459dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson    public void onSaveInstanceState(Bundle outState) {
30559dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson        super.onSaveInstanceState(outState);
3064715cafcbe76ac79b0b25ec62ec4ad8b55a2d41dMakoto Onuki        outState.putParcelable(EXTRA_KEY_GROUP_URI, mSelectedGroupUri);
30759dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson    }
30866606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson
30966606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson    public void setAddAccountsVisibility(boolean visible) {
31066606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson        if (mAddAccountsView != null) {
31166606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson            mAddAccountsView.setVisibility(visible ? View.VISIBLE : View.GONE);
31266606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson        }
31366606b648d7eee16b6e5a55506bbee141887b55eIsaac Katzenelson    }
3149add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan}
315