blob: f6898b54fac5da145f58ad231d8668418d42d995 [file] [log] [blame]
/*
* Copyright (C) 2017 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.drawer;
import android.app.Activity;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.provider.ContactsContract.DisplayNameSources;
import androidx.annotation.LayoutRes;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.contacts.ContactPhotoManager;
import com.android.contacts.R;
import com.android.contacts.activities.PeopleActivity.ContactsView;
import com.android.contacts.group.GroupListItem;
import com.android.contacts.list.ContactListFilter;
import com.android.contacts.model.account.AccountDisplayInfo;
import com.android.contacts.model.account.AccountDisplayInfoFactory;
import com.android.contacts.profile.ProfileItem;
import com.android.contacts.util.ImplicitIntentsUtil;
import com.android.contacts.util.SharedPreferenceUtil;
import com.android.contactsbind.HelpUtils;
import com.android.contactsbind.ObjectFactory;
import java.util.ArrayList;
import java.util.List;
public class DrawerAdapter extends BaseAdapter {
private static final int VIEW_TYPE_PRIMARY_ITEM = 0;
private static final int VIEW_TYPE_MISC_ITEM = 1;
private static final int VIEW_TYPE_HEADER_ITEM = 2;
private static final int VIEW_TYPE_GROUP_ENTRY = 3;
private static final int VIEW_TYPE_ACCOUNT_ENTRY = 4;
private static final int VIEW_TYPE_CREATE_LABEL = 5;
private static final int VIEW_TYPE_NAV_SPACER = 6;
private static final int VIEW_TYPE_NAV_DIVIDER = 7;
private static final int VIEW_TYPE_PROFILE_ENTRY = 8;
private static final int VIEW_TYPE_EMERGENCY_ITEM = 9;
// This count must be updated if we add more view types.
private static final int VIEW_TYPE_COUNT = 11;
private static final int TYPEFACE_STYLE_ACTIVATE = R.style.DrawerItemTextActiveStyle;
private static final int TYPEFACE_STYLE_INACTIVE = R.style.DrawerItemTextInactiveStyle;
private final Activity mActivity;
private final LayoutInflater mInflater;
private ContactsView mSelectedView;
private boolean mAreGroupWritableAccountsAvailable;
// The group/account that was last clicked.
private long mSelectedGroupId;
private ContactListFilter mSelectedAccount;
// Adapter elements, ordered in this way mItemsList. The ordering is based on:
// [Navigation spacer item]
// [Profile Entry item]
// [Primary items] (Contacts, Suggestions)
// [Group Header]
// [Groups]
// [Create Label button]
// [Account Header]
// [Accounts]
// [Emergency information]
// [Emergency information spacer item]
// [Misc items] (a divider, Settings, Help & Feedback)
// [Navigation spacer item]
private NavSpacerItem mNavSpacerItem = null;
private ProfileEntryItem mProfileEntryItem = null;
private DividerItem mProfileEntryItemDivider = null;
private List<PrimaryItem> mPrimaryItems = new ArrayList<>();
private HeaderItem mGroupHeader = null;
private List<GroupEntryItem> mGroupEntries = new ArrayList<>();
private BaseDrawerItem mCreateLabelButton = null;
private HeaderItem mAccountHeader = null;
private List<AccountEntryItem> mAccountEntries = new ArrayList<>();
private BaseDrawerItem mEmergencyItem = null;
private DividerItem mEmergencyItemDivider = null;
private List<BaseDrawerItem> mMiscItems = new ArrayList<>();
private List<BaseDrawerItem> mItemsList = new ArrayList<>();
private AccountDisplayInfoFactory mAccountDisplayFactory;
public DrawerAdapter(Activity activity) {
super();
mInflater = LayoutInflater.from(activity);
mActivity = activity;
initializeDrawerMenuItems();
}
private void initializeDrawerMenuItems() {
// Spacer item for dividing sections in drawer
mNavSpacerItem = new NavSpacerItem(R.id.nav_drawer_spacer);
mProfileEntryItemDivider = new DividerItem();
// Primary items
mPrimaryItems.add(new PrimaryItem(R.id.nav_all_contacts, R.string.contactsList,
R.drawable.quantum_ic_account_circle_vd_theme_24, ContactsView.ALL_CONTACTS));
if (ObjectFactory.getAssistantFragment() != null) {
mPrimaryItems.add(new PrimaryItem(R.id.nav_assistant, R.string.menu_assistant,
R.drawable.quantum_ic_assistant_vd_theme_24, ContactsView.ASSISTANT));
}
// Group Header
mGroupHeader = new HeaderItem(R.id.nav_groups, R.string.menu_title_groups);
// Account Header
mAccountHeader = new HeaderItem(R.id.nav_filters, R.string.menu_title_filters);
// Create Label Button
mCreateLabelButton = new BaseDrawerItem(VIEW_TYPE_CREATE_LABEL, R.id.nav_create_label,
R.string.menu_new_group_action_bar, R.drawable.quantum_ic_add_vd_theme_24);
// Emergency information Item
mEmergencyItem = new BaseDrawerItem(VIEW_TYPE_EMERGENCY_ITEM, R.id.nav_emergency,
R.string.menu_emergency_information_txt,
R.drawable.quantum_ic_drawer_emergency_info_24);
mEmergencyItemDivider = new DividerItem();
// Misc Items
mMiscItems.add(new DividerItem());
mMiscItems.add(new MiscItem(R.id.nav_settings, R.string.menu_settings,
R.drawable.quantum_ic_settings_vd_theme_24));
if (HelpUtils.isHelpAndFeedbackAvailable()) {
mMiscItems.add(new MiscItem(R.id.nav_help, R.string.menu_help,
R.drawable.quantum_ic_help_vd_theme_24));
}
rebuildItemsList();
}
private void rebuildItemsList() {
mItemsList.clear();
mItemsList.add(mNavSpacerItem);
if (mProfileEntryItem != null) {
mItemsList.add(mProfileEntryItem);
mItemsList.add(mProfileEntryItemDivider);
}
mItemsList.addAll(mPrimaryItems);
if (mAreGroupWritableAccountsAvailable || !mGroupEntries.isEmpty()) {
mItemsList.add(mGroupHeader);
}
mItemsList.addAll(mGroupEntries);
if (mAreGroupWritableAccountsAvailable) {
mItemsList.add(mCreateLabelButton);
}
if (mAccountEntries.size() > 0) {
mItemsList.add(mAccountHeader);
}
mItemsList.addAll(mAccountEntries);
if (ImplicitIntentsUtil.getIntentForEmergencyInfo(mActivity) != null) {
mItemsList.add(mEmergencyItemDivider);
mItemsList.add(mEmergencyItem);
}
mItemsList.addAll(mMiscItems);
mItemsList.add(mNavSpacerItem);
}
public void setProfile(ProfileItem profileItem) {
mProfileEntryItem = new ProfileEntryItem(R.id.nav_myprofile, profileItem);
notifyChangeAndRebuildList();
}
public void setGroups(List<GroupListItem> groupListItems, boolean areGroupWritable) {
final ArrayList<GroupEntryItem> groupEntries = new ArrayList<GroupEntryItem>();
for (GroupListItem group : groupListItems) {
groupEntries.add(new GroupEntryItem(R.id.nav_group, group));
}
mGroupEntries.clear();
mGroupEntries.addAll(groupEntries);
mAreGroupWritableAccountsAvailable = areGroupWritable;
notifyChangeAndRebuildList();
}
public void setAccounts(List<ContactListFilter> accountFilterItems) {
ArrayList<AccountEntryItem> accountItems = new ArrayList<AccountEntryItem>();
for (ContactListFilter filter : accountFilterItems) {
accountItems.add(new AccountEntryItem(R.id.nav_filter, filter));
}
mAccountDisplayFactory = AccountDisplayInfoFactory.fromListFilters(mActivity,
accountFilterItems);
mAccountEntries.clear();
mAccountEntries.addAll(accountItems);
// TODO investigate performance of calling notifyDataSetChanged
notifyChangeAndRebuildList();
}
@Override
public int getCount() {
return mItemsList.size();
}
public BaseDrawerItem getItem(int position) {
return mItemsList.get(position);
}
@Override
public long getItemId(int position) {
return getItem(position).id;
}
@Override
public int getViewTypeCount() {
return VIEW_TYPE_COUNT;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
final BaseDrawerItem drawerItem = getItem(position);
switch (drawerItem.viewType) {
case VIEW_TYPE_PROFILE_ENTRY:
return getProfileEntryView((ProfileEntryItem) drawerItem, view, viewGroup);
case VIEW_TYPE_PRIMARY_ITEM:
return getPrimaryItemView((PrimaryItem) drawerItem, view, viewGroup);
case VIEW_TYPE_HEADER_ITEM:
return getHeaderItemView((HeaderItem) drawerItem, view, viewGroup);
case VIEW_TYPE_CREATE_LABEL:
return getDrawerItemView(drawerItem, view, viewGroup);
case VIEW_TYPE_GROUP_ENTRY:
return getGroupEntryView((GroupEntryItem) drawerItem, view, viewGroup);
case VIEW_TYPE_ACCOUNT_ENTRY:
return getAccountItemView((AccountEntryItem) drawerItem, view, viewGroup);
case VIEW_TYPE_MISC_ITEM:
return getDrawerItemView(drawerItem, view, viewGroup);
case VIEW_TYPE_NAV_SPACER:
return getBaseItemView(R.layout.nav_drawer_spacer, view, viewGroup);
case VIEW_TYPE_NAV_DIVIDER:
return getBaseItemView(R.layout.drawer_horizontal_divider, view, viewGroup);
case VIEW_TYPE_EMERGENCY_ITEM:
return getDrawerItemView(drawerItem, view, viewGroup);
}
throw new IllegalStateException("Unknown drawer item " + drawerItem);
}
private View getBaseItemView(@LayoutRes int layoutResID, View result,ViewGroup parent) {
if (result == null) {
result = mInflater.inflate(layoutResID, parent, false);
}
return result;
}
private View getPrimaryItemView(PrimaryItem item, View result, ViewGroup parent) {
if (result == null) {
result = mInflater.inflate(R.layout.drawer_primary_item, parent, false);
}
final TextView titleView = (TextView) result.findViewById(R.id.title);
titleView.setText(item.text);
final ImageView iconView = (ImageView) result.findViewById(R.id.icon);
iconView.setImageResource(item.icon);
final TextView newBadge = (TextView) result.findViewById(R.id.assistant_new_badge);
final boolean showWelcomeBadge = !SharedPreferenceUtil.isWelcomeCardDismissed(mActivity);
newBadge.setVisibility(item.contactsView == ContactsView.ASSISTANT && showWelcomeBadge
? View.VISIBLE : View.GONE);
result.setActivated(item.contactsView == mSelectedView);
updateSelectedStatus(titleView, iconView, item.contactsView == mSelectedView);
result.setId(item.id);
return result;
}
private View getHeaderItemView(HeaderItem item, View result, ViewGroup parent) {
if (result == null) {
result = mInflater.inflate(R.layout.drawer_header, parent, false);
}
final TextView textView = (TextView) result.findViewById(R.id.title);
textView.setText(item.text);
result.setId(item.id);
return result;
}
private View getProfileEntryView(ProfileEntryItem item, View result, ViewGroup parent) {
if (result == null) {
result = mInflater.inflate(R.layout.drawer_secondline_item, parent, false);
result.setId(item.id);
}
final ProfileItem profile = item.profile;
final ImageView icon = (ImageView) result.findViewById(R.id.icon);
icon.setScaleType(ImageView.ScaleType.CENTER);
if (profile.HasProfile()) {
if (profile.getPhotoId() != 0) {
icon.setScaleType(ImageView.ScaleType.FIT_CENTER);
getPhotoLoader().loadThumbnail(icon, profile.getPhotoId(), false, true, null);
} else if (profile.getPhotoUri() != null) {
icon.setScaleType(ImageView.ScaleType.FIT_CENTER);
getPhotoLoader().loadDirectoryPhoto(icon, Uri.parse(profile.getPhotoUri()), false,
true, null);
} else {
// There are cases where the image cache may remain, so update once by default.
getPhotoLoader().loadDirectoryPhoto(icon, null, false, true, null);
icon.setImageResource(R.drawable.quantum_ic_drawer_my_info_32);
}
} else {
// There are cases where the image cache may remain, so update once by default.
getPhotoLoader().loadDirectoryPhoto(icon, null, false, true, null);
icon.setImageResource(R.drawable.quantum_ic_drawer_my_info_32);
}
final TextView title = (TextView) result.findViewById(R.id.title);
title.setText(mActivity.getString(R.string.settings_my_info_title));
final TextView summary = (TextView) result.findViewById(R.id.summary);
if (profile.HasProfile()) {
summary.setText(profile.getDisplayName());
if (profile.getDisplayNameSource() == DisplayNameSources.PHONE) {
summary.setTextDirection(TextView.TEXT_DIRECTION_LTR);
}
} else {
summary.setText(mActivity.getString(R.string.set_up_profile));
}
// Apply setTextAppearance to title only.
updateSelectedStatus(title, icon, false);
result.setTag(profile.HasProfile() ? profile.getContactId() : -1);
return result;
}
private View getGroupEntryView(GroupEntryItem item, View result, ViewGroup parent) {
if (result == null || !(result.getTag() instanceof GroupEntryItem)) {
result = mInflater.inflate(R.layout.drawer_item, parent, false);
result.setId(item.id);
}
final GroupListItem groupListItem = item.group;
final TextView title = (TextView) result.findViewById(R.id.title);
title.setText(groupListItem.getTitle());
final ImageView icon = (ImageView) result.findViewById(R.id.icon);
icon.setImageResource(R.drawable.quantum_ic_label_vd_theme_24);
final boolean activated = groupListItem.getGroupId() == mSelectedGroupId &&
mSelectedView == ContactsView.GROUP_VIEW;
updateSelectedStatus(title, icon, activated);
result.setActivated(activated);
result.setTag(groupListItem);
result.setContentDescription(
mActivity.getString(R.string.navigation_drawer_label, groupListItem.getTitle()));
return result;
}
private View getAccountItemView(AccountEntryItem item, View result, ViewGroup parent) {
if (result == null || !(result.getTag() instanceof ContactListFilter)) {
result = mInflater.inflate(R.layout.drawer_item, parent, false);
result.setId(item.id);
}
final ContactListFilter account = item.account;
final AccountDisplayInfo displayableAccount =
mAccountDisplayFactory.getAccountDisplayInfoFor(item.account);
final TextView textView = ((TextView) result.findViewById(R.id.title));
textView.setText(mActivity.getPackageName().equals(account.accountType) ?
mActivity.getString(R.string.account_phone) : displayableAccount.getNameLabel());
final boolean activated = account.equals(mSelectedAccount)
&& mSelectedView == ContactsView.ACCOUNT_VIEW;
textView.setTextAppearance(mActivity, activated
? TYPEFACE_STYLE_ACTIVATE : TYPEFACE_STYLE_INACTIVE);
final ImageView icon = (ImageView) result.findViewById(R.id.icon);
icon.setScaleType(ImageView.ScaleType.FIT_CENTER);
icon.setImageDrawable(displayableAccount.getIcon());
result.setTag(account);
result.setActivated(activated);
result.setContentDescription(
displayableAccount.getTypeLabel() + " " + item.account.accountName);
return result;
}
private View getDrawerItemView(BaseDrawerItem item, View result, ViewGroup parent) {
if (result == null) {
result = mInflater.inflate(R.layout.drawer_item, parent, false);
}
final TextView textView = (TextView) result.findViewById(R.id.title);
textView.setText(item.text);
final ImageView iconView = (ImageView) result.findViewById(R.id.icon);
iconView.setImageResource(item.icon);
result.setId(item.id);
updateSelectedStatus(textView, iconView, false);
return result;
}
@Override
public int getItemViewType(int position) {
return getItem(position).viewType;
}
private void updateSelectedStatus(TextView textView, ImageView imageView, boolean activated) {
textView.setTextAppearance(mActivity, activated
? TYPEFACE_STYLE_ACTIVATE : TYPEFACE_STYLE_INACTIVE);
if (activated) {
imageView.setColorFilter(mActivity.getResources().getColor(R.color.primary_color),
PorterDuff.Mode.SRC_ATOP);
} else {
imageView.clearColorFilter();
}
}
private void notifyChangeAndRebuildList() {
rebuildItemsList();
notifyDataSetChanged();
}
public void setSelectedContactsView(ContactsView contactsView) {
if (mSelectedView == contactsView) {
return;
}
mSelectedView = contactsView;
notifyChangeAndRebuildList();
}
public void setSelectedGroupId(long groupId) {
if (mSelectedGroupId == groupId) {
return;
}
mSelectedGroupId = groupId;
notifyChangeAndRebuildList();
}
public long getSelectedGroupId() {
return mSelectedGroupId;
}
public void setSelectedAccount(ContactListFilter filter) {
if (mSelectedAccount == filter) {
return;
}
mSelectedAccount = filter;
notifyChangeAndRebuildList();
}
public ContactListFilter getSelectedAccount() {
return mSelectedAccount;
}
public static class BaseDrawerItem {
public final int viewType;
public final int id;
public final int text;
public final int icon;
public BaseDrawerItem(int adapterViewType, int viewId, int textResId, int iconResId) {
viewType = adapterViewType;
id = viewId;
text = textResId;
icon = iconResId;
}
}
// Navigation drawer item for Contacts or Suggestions view which contains a name, an icon and
// contacts view.
public static class PrimaryItem extends BaseDrawerItem {
public final ContactsView contactsView;
public PrimaryItem(int id, int pageName, int iconId, ContactsView contactsView) {
super(VIEW_TYPE_PRIMARY_ITEM, id, pageName, iconId);
this.contactsView = contactsView;
}
}
// Navigation drawer item for Settings, help and feedback, etc.
public static class MiscItem extends BaseDrawerItem {
public MiscItem(int id, int textId, int iconId) {
super(VIEW_TYPE_MISC_ITEM, id, textId, iconId);
}
}
// Header for a list of sub-items in the drawer.
public static class HeaderItem extends BaseDrawerItem {
public HeaderItem(int id, int textId) {
super(VIEW_TYPE_HEADER_ITEM, id, textId, /* iconResId */ 0);
}
}
// Navigation drawer item for spacer item for dividing sections in the drawer.
public static class NavSpacerItem extends BaseDrawerItem {
public NavSpacerItem(int id) {
super(VIEW_TYPE_NAV_SPACER, id, /* textResId */ 0, /* iconResId */ 0);
}
}
// Divider for drawing a line between sections in the drawer.
public static class DividerItem extends BaseDrawerItem {
public DividerItem() {
super(VIEW_TYPE_NAV_DIVIDER, /* id */ 0, /* textResId */ 0, /* iconResId */ 0);
}
}
// Navigation drawer item for a profile.
public static class ProfileEntryItem extends BaseDrawerItem {
private final ProfileItem profile;
public ProfileEntryItem(int id, ProfileItem profileItem) {
super(VIEW_TYPE_PROFILE_ENTRY, id, /* textResId */ 0, /* iconResId */ 0);
this.profile = profileItem;
}
}
// Navigation drawer item for a group.
public static class GroupEntryItem extends BaseDrawerItem {
private final GroupListItem group;
public GroupEntryItem(int id, GroupListItem group) {
super(VIEW_TYPE_GROUP_ENTRY, id, /* textResId */ 0, /* iconResId */ 0);
this.group = group;
}
}
// Navigation drawer item for an account.
public static class AccountEntryItem extends BaseDrawerItem {
private final ContactListFilter account;
public AccountEntryItem(int id, ContactListFilter account) {
super(VIEW_TYPE_ACCOUNT_ENTRY, id, /* textResId */ 0, /* iconResId */ 0);
this.account = account;
}
}
private ContactPhotoManager getPhotoLoader() {
return ContactPhotoManager.getInstance(mActivity);
}
}