| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| |
| package com.android.contacts.group; |
| |
| import com.android.contacts.ContactPhotoManager; |
| import com.android.contacts.GroupMemberLoader; |
| import com.android.contacts.GroupMetaDataLoader; |
| import com.android.contacts.R; |
| import com.android.contacts.interactions.GroupDeletionDialogFragment; |
| import com.android.contacts.list.ContactTileAdapter; |
| import com.android.contacts.list.ContactTileAdapter.DisplayType; |
| |
| import android.app.Activity; |
| import android.app.Fragment; |
| import android.app.LoaderManager; |
| import android.app.LoaderManager.LoaderCallbacks; |
| import android.content.Context; |
| import android.content.CursorLoader; |
| import android.content.Loader; |
| import android.content.res.Resources; |
| import android.database.Cursor; |
| import android.net.Uri; |
| import android.os.Bundle; |
| import android.util.Log; |
| import android.view.LayoutInflater; |
| import android.view.Menu; |
| import android.view.MenuInflater; |
| import android.view.MenuItem; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.widget.AbsListView; |
| import android.widget.AbsListView.OnScrollListener; |
| import android.widget.ListView; |
| import android.widget.TextView; |
| |
| /** |
| * Displays the details of a group and shows a list of actions possible for the group. |
| */ |
| public class GroupDetailFragment extends Fragment implements OnScrollListener { |
| |
| public static interface Listener { |
| /** |
| * The group title has been loaded |
| */ |
| public void onGroupTitleUpdated(String title); |
| |
| /** |
| * The number of group members has been determined |
| */ |
| public void onGroupSizeUpdated(String size); |
| |
| /** |
| * User decided to go to Edit-Mode |
| */ |
| public void onEditRequested(Uri groupUri); |
| } |
| |
| private static final String TAG = "GroupDetailFragment"; |
| |
| private static final int LOADER_METADATA = 0; |
| private static final int LOADER_MEMBERS = 1; |
| |
| private Context mContext; |
| |
| private View mRootView; |
| private TextView mGroupTitle; |
| private TextView mGroupSize; |
| private ListView mMemberListView; |
| |
| private Listener mListener; |
| |
| private ContactTileAdapter mAdapter; |
| private ContactPhotoManager mPhotoManager; |
| |
| private Uri mGroupUri; |
| private long mGroupId; |
| private String mGroupName; |
| |
| private boolean mOptionsMenuEditable; |
| private boolean mCloseActivityAfterDelete; |
| |
| public GroupDetailFragment() { |
| } |
| |
| @Override |
| public void onAttach(Activity activity) { |
| super.onAttach(activity); |
| mContext = activity; |
| |
| Resources res = getResources(); |
| int columnCount = res.getInteger(R.integer.contact_tile_column_count); |
| |
| mAdapter = new ContactTileAdapter(activity, mContactTileListener, columnCount, |
| DisplayType.GROUP_MEMBERS); |
| |
| configurePhotoLoader(); |
| } |
| |
| @Override |
| public void onDetach() { |
| super.onDetach(); |
| mContext = null; |
| } |
| |
| @Override |
| public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { |
| setHasOptionsMenu(true); |
| mRootView = inflater.inflate(R.layout.group_detail_fragment, container, false); |
| mGroupTitle = (TextView) mRootView.findViewById(R.id.group_title); |
| mGroupSize = (TextView) mRootView.findViewById(R.id.group_size); |
| mMemberListView = (ListView) mRootView.findViewById(android.R.id.list); |
| |
| return mRootView; |
| } |
| |
| public void loadGroup(Uri groupUri) { |
| mGroupUri= groupUri; |
| startGroupMetadataLoader(); |
| } |
| |
| public void setQuickContact(boolean enableQuickContact) { |
| mAdapter.setQuickContact(enableQuickContact); |
| } |
| |
| private void configureAdapter(long groupId) { |
| mGroupId = groupId; |
| mMemberListView.setAdapter(mAdapter); |
| } |
| |
| private void configurePhotoLoader() { |
| if (mContext != null) { |
| if (mPhotoManager == null) { |
| mPhotoManager = ContactPhotoManager.getInstance(mContext); |
| } |
| if (mMemberListView != null) { |
| mMemberListView.setOnScrollListener(this); |
| } |
| if (mAdapter != null) { |
| mAdapter.setPhotoLoader(mPhotoManager); |
| } |
| } |
| } |
| |
| public void setListener(Listener value) { |
| mListener = value; |
| } |
| |
| /** |
| * Start the loader to retrieve the metadata for this group. |
| */ |
| private void startGroupMetadataLoader() { |
| getLoaderManager().destroyLoader(LOADER_METADATA); |
| getLoaderManager().restartLoader(LOADER_METADATA, null, mGroupMetadataLoaderListener); |
| } |
| |
| /** |
| * Start the loader to retrieve the list of group members. |
| */ |
| private void startGroupMembersLoader() { |
| getLoaderManager().destroyLoader(LOADER_MEMBERS); |
| getLoaderManager().restartLoader(LOADER_MEMBERS, null, mGroupMemberListLoaderListener); |
| } |
| |
| private final ContactTileAdapter.Listener mContactTileListener = |
| new ContactTileAdapter.Listener() { |
| |
| @Override |
| public void onContactSelected(Uri contactUri) { |
| // TODO: Launch Quick Contact |
| } |
| }; |
| |
| /** |
| * The listener for the group metadata loader. |
| */ |
| private final LoaderManager.LoaderCallbacks<Cursor> mGroupMetadataLoaderListener = |
| new LoaderCallbacks<Cursor>() { |
| |
| @Override |
| public CursorLoader onCreateLoader(int id, Bundle args) { |
| return new GroupMetaDataLoader(mContext, mGroupUri); |
| } |
| |
| @Override |
| public void onLoadFinished(Loader<Cursor> loader, Cursor data) { |
| data.moveToPosition(-1); |
| if (data.moveToNext()) { |
| boolean deleted = data.getInt(GroupMetaDataLoader.DELETED) == 1; |
| if (!deleted) { |
| bindGroupMetaData(data); |
| |
| // Retrieve the list of members |
| configureAdapter(mGroupId); |
| startGroupMembersLoader(); |
| return; |
| } |
| } |
| updateSize(null); |
| updateTitle(null); |
| } |
| |
| @Override |
| public void onLoaderReset(Loader<Cursor> loader) {} |
| }; |
| |
| /** |
| * The listener for the group members list loader |
| */ |
| private final LoaderManager.LoaderCallbacks<Cursor> mGroupMemberListLoaderListener = |
| new LoaderCallbacks<Cursor>() { |
| |
| @Override |
| public CursorLoader onCreateLoader(int id, Bundle args) { |
| return new GroupMemberLoader(mContext, mGroupId); |
| } |
| |
| @Override |
| public void onLoadFinished(Loader<Cursor> loader, Cursor data) { |
| updateSize(Integer.toString(data.getCount())); |
| mAdapter.loadFromCursor(data); |
| } |
| |
| @Override |
| public void onLoaderReset(Loader<Cursor> loader) {} |
| }; |
| |
| private void bindGroupMetaData(Cursor cursor) { |
| cursor.moveToPosition(-1); |
| if (cursor.moveToNext()) { |
| mGroupId = cursor.getLong(GroupMetaDataLoader.GROUP_ID); |
| mGroupName = cursor.getString(GroupMetaDataLoader.TITLE); |
| updateTitle(mGroupName); |
| |
| // TODO: Replace by real button |
| final String action = cursor.getString(GroupMetaDataLoader.ACTION); |
| final String actionUri = cursor.getString(GroupMetaDataLoader.ACTION_URI); |
| Log.d(TAG, "Group open action: " + action + ", uri: " + actionUri); |
| } |
| } |
| |
| private void updateTitle(String title) { |
| if (mGroupTitle != null) { |
| mGroupTitle.setText(title); |
| } else { |
| mListener.onGroupTitleUpdated(title); |
| } |
| } |
| |
| private void updateSize(String size) { |
| if (mGroupSize != null) { |
| mGroupSize.setText(size); |
| } else { |
| mListener.onGroupSizeUpdated(size); |
| } |
| } |
| |
| @Override |
| public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, |
| int totalItemCount) { |
| } |
| |
| @Override |
| public void onScrollStateChanged(AbsListView view, int scrollState) { |
| if (scrollState == OnScrollListener.SCROLL_STATE_FLING) { |
| mPhotoManager.pause(); |
| } else { |
| mPhotoManager.resume(); |
| } |
| } |
| |
| @Override |
| public void onCreateOptionsMenu(Menu menu, final MenuInflater inflater) { |
| inflater.inflate(R.menu.view_group, menu); |
| } |
| |
| public boolean isOptionsMenuChanged() { |
| return mOptionsMenuEditable != isGroupEditable(); |
| } |
| |
| public boolean isGroupEditable() { |
| // TODO: This should check the group_is_read_only flag. Modify GroupMetaDataLoader. |
| // Bug: 4601729. |
| return mGroupUri != null; |
| } |
| |
| @Override |
| public void onPrepareOptionsMenu(Menu menu) { |
| mOptionsMenuEditable = isGroupEditable(); |
| |
| final MenuItem editMenu = menu.findItem(R.id.menu_edit_group); |
| editMenu.setVisible(mOptionsMenuEditable); |
| |
| final MenuItem deleteMenu = menu.findItem(R.id.menu_delete_group); |
| deleteMenu.setVisible(mOptionsMenuEditable); |
| } |
| |
| @Override |
| public boolean onOptionsItemSelected(MenuItem item) { |
| switch (item.getItemId()) { |
| case R.id.menu_edit_group: { |
| if (mListener != null) mListener.onEditRequested(mGroupUri); |
| break; |
| } |
| case R.id.menu_delete_group: { |
| GroupDeletionDialogFragment.show(getFragmentManager(), mGroupId, mGroupName, |
| mCloseActivityAfterDelete); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| public void closeActivityAfterDelete(boolean closeActivity) { |
| mCloseActivityAfterDelete = closeActivity; |
| } |
| } |