/* * Copyright (C) 2010 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.list; import com.android.contacts.R; import com.android.contacts.editor.ContactEditorFragment; import com.android.contacts.util.AccountFilterUtil; import android.content.CursorLoader; import android.content.Intent; import android.database.Cursor; import android.provider.ContactsContract.Contacts; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; /** * Fragment containing a contact list used for browsing (as compared to * picking a contact with one of the PICK intents). */ public class DefaultContactBrowseListFragment extends ContactBrowseListFragment { private static final String TAG = DefaultContactBrowseListFragment.class.getSimpleName(); private static final int REQUEST_CODE_ACCOUNT_FILTER = 1; private TextView mCounterHeaderView; private View mSearchHeaderView; private View mAccountFilterHeader; private FrameLayout mProfileHeaderContainer; private View mProfileHeader; private Button mProfileMessage; private FrameLayout mMessageContainer; private TextView mProfileTitle; private View mPaddingView; private class FilterHeaderClickListener implements OnClickListener { @Override public void onClick(View view) { AccountFilterUtil.startAccountFilterActivityForResult( DefaultContactBrowseListFragment.this, REQUEST_CODE_ACCOUNT_FILTER); } } private OnClickListener mFilterHeaderClickListener = new FilterHeaderClickListener(); public DefaultContactBrowseListFragment() { setPhotoLoaderEnabled(true); setSectionHeaderDisplayEnabled(true); setVisibleScrollbarEnabled(true); } @Override public CursorLoader createCursorLoader() { return new ProfileAndContactsLoader(getActivity()); } @Override protected void onItemClick(int position, long id) { viewContact(getAdapter().getContactUri(position)); } @Override protected ContactListAdapter createListAdapter() { DefaultContactListAdapter adapter = new DefaultContactListAdapter(getContext()); adapter.setSectionHeaderDisplayEnabled(isSectionHeaderDisplayEnabled()); adapter.setDisplayPhotos(true); return adapter; } @Override protected View inflateView(LayoutInflater inflater, ViewGroup container) { return inflater.inflate(R.layout.contact_list_content, null); } @Override protected void onCreateView(LayoutInflater inflater, ViewGroup container) { super.onCreateView(inflater, container); mAccountFilterHeader = getView().findViewById(R.id.account_filter_header_container); mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener); mCounterHeaderView = (TextView) getView().findViewById(R.id.contacts_count); // Create an empty user profile header and hide it for now (it will be visible if the // contacts list will have no user profile). addEmptyUserProfileHeader(inflater); showEmptyUserProfile(false); // Putting the header view inside a container will allow us to make // it invisible later. See checkHeaderViewVisibility() FrameLayout headerContainer = new FrameLayout(inflater.getContext()); mSearchHeaderView = inflater.inflate(R.layout.search_header, null, false); headerContainer.addView(mSearchHeaderView); getListView().addHeaderView(headerContainer, null, false); checkHeaderViewVisibility(); } @Override protected void setSearchMode(boolean flag) { super.setSearchMode(flag); checkHeaderViewVisibility(); } private void checkHeaderViewVisibility() { if (mCounterHeaderView != null) { mCounterHeaderView.setVisibility(isSearchMode() ? View.GONE : View.VISIBLE); } updateFilterHeaderView(); // Hide the search header by default. See showCount(). if (mSearchHeaderView != null) { mSearchHeaderView.setVisibility(View.GONE); } } @Override public void setFilter(ContactListFilter filter) { super.setFilter(filter); updateFilterHeaderView(); } private void updateFilterHeaderView() { if (mAccountFilterHeader == null) { return; // Before onCreateView -- just ignore it. } final ContactListFilter filter = getFilter(); if (filter != null && !isSearchMode()) { final boolean shouldShowHeader = AccountFilterUtil.updateAccountFilterTitleForPeople( mAccountFilterHeader, filter, false, false); mAccountFilterHeader.setVisibility(shouldShowHeader ? View.VISIBLE : View.GONE); } else { mAccountFilterHeader.setVisibility(View.GONE); } } @Override protected void showCount(int partitionIndex, Cursor data) { if (!isSearchMode() && data != null) { int count = data.getCount(); if (count != 0) { count -= (mUserProfileExists ? 1: 0); String format = getResources().getQuantityText( R.plurals.listTotalAllContacts, count).toString(); // Do not count the user profile in the contacts count if (mUserProfileExists) { getAdapter().setContactsCount(String.format(format, count)); } else { mCounterHeaderView.setText(String.format(format, count)); } } else { ContactListFilter filter = getFilter(); int filterType = filter != null ? filter.filterType : ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS; switch (filterType) { case ContactListFilter.FILTER_TYPE_ACCOUNT: mCounterHeaderView.setText(getString( R.string.listTotalAllContactsZeroGroup, filter.accountName)); break; case ContactListFilter.FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY: mCounterHeaderView.setText(R.string.listTotalPhoneContactsZero); break; case ContactListFilter.FILTER_TYPE_STARRED: mCounterHeaderView.setText(R.string.listTotalAllContactsZeroStarred); break; case ContactListFilter.FILTER_TYPE_CUSTOM: mCounterHeaderView.setText(R.string.listTotalAllContactsZeroCustom); break; default: mCounterHeaderView.setText(R.string.listTotalAllContactsZero); break; } } } else { ContactListAdapter adapter = getAdapter(); if (adapter == null) { return; } // In search mode we only display the header if there is nothing found if (TextUtils.isEmpty(getQueryString()) || !adapter.areAllPartitionsEmpty()) { mSearchHeaderView.setVisibility(View.GONE); } else { TextView textView = (TextView) mSearchHeaderView.findViewById( R.id.totalContactsText); ProgressBar progress = (ProgressBar) mSearchHeaderView.findViewById( R.id.progress); mSearchHeaderView.setVisibility(View.VISIBLE); if (adapter.isLoading()) { textView.setText(R.string.search_results_searching); progress.setVisibility(View.VISIBLE); } else { textView.setText(R.string.listFoundAllContactsZero); textView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); progress.setVisibility(View.GONE); } } showEmptyUserProfile(false); } } @Override protected void setProfileHeader() { mUserProfileExists = getAdapter().hasProfile(); showEmptyUserProfile(!mUserProfileExists && !isSearchMode()); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_ACCOUNT_FILTER) { if (getActivity() != null) { AccountFilterUtil.handleAccountFilterResult( ContactListFilterController.getInstance(getActivity()), resultCode, data); } else { Log.e(TAG, "getActivity() returns null during Fragment#onActivityResult()"); } } } private void showEmptyUserProfile(boolean show) { // Changing visibility of just the mProfileHeader doesn't do anything unless // you change visibility of its children, hence the call to mCounterHeaderView // and mProfileTitle mProfileHeaderContainer.setVisibility(show ? View.VISIBLE : View.GONE); mProfileHeader.setVisibility(show ? View.VISIBLE : View.GONE); mCounterHeaderView.setVisibility(show ? View.VISIBLE : View.GONE); mProfileTitle.setVisibility(show ? View.VISIBLE : View.GONE); mMessageContainer.setVisibility(show ? View.VISIBLE : View.GONE); mProfileMessage.setVisibility(show ? View.VISIBLE : View.GONE); mPaddingView.setVisibility(show ? View.GONE : View.VISIBLE); } /** * This method creates a pseudo user profile contact. When the returned query doesn't have * a profile, this methods creates 2 views that are inserted as headers to the listview: * 1. A header view with the "ME" title and the contacts count. * 2. A button that prompts the user to create a local profile */ private void addEmptyUserProfileHeader(LayoutInflater inflater) { ListView list = getListView(); // Put a header with the "ME" name and a view for the number of contacts // The view is embedded in a frame view since you cannot change the visibility of a // view in a ListView without having a parent view. mProfileHeaderContainer = new FrameLayout(inflater.getContext()); mProfileHeader = inflater.inflate(R.layout.user_profile_header, null, false); mCounterHeaderView = (TextView) mProfileHeader.findViewById(R.id.contacts_count); mProfileTitle = (TextView) mProfileHeader.findViewById(R.id.profile_title); mProfileTitle.setAllCaps(true); mProfileHeaderContainer.addView(mProfileHeader); list.addHeaderView(mProfileHeaderContainer, null, false); // Add a selectable view with a message inviting the user to create a local profile mMessageContainer = new FrameLayout(inflater.getContext()); mProfileMessage = (Button)inflater.inflate(R.layout.user_profile_button, null, false); mMessageContainer.addView(mProfileMessage); list.addHeaderView(mMessageContainer, null, true); mProfileMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI); intent.putExtra(ContactEditorFragment.INTENT_EXTRA_NEW_LOCAL_PROFILE, true); startActivity(intent); } }); View paddingViewContainer = inflater.inflate(R.layout.contact_detail_list_padding, null, false); mPaddingView = paddingViewContainer.findViewById(R.id.contact_detail_list_padding); mPaddingView.setVisibility(View.GONE); getListView().addHeaderView(paddingViewContainer); } }