diff options
22 files changed, 1130 insertions, 450 deletions
diff --git a/res/drawable/drawer_item_background.xml b/res/drawable/drawer_item_background.xml index 88f6690a0..dc8a9f248 100644 --- a/res/drawable/drawer_item_background.xml +++ b/res/drawable/drawer_item_background.xml @@ -14,12 +14,9 @@ limitations under the License. --> -<ripple xmlns:android="http://schemas.android.com/apk/res/android" - android:color="@color/nav_item_selected_background"> - <item> - <selector> - <item android:drawable="@color/nav_item_selected_background" android:state_checked="true"/> - <item android:drawable="@android:color/transparent"/> - </selector> - </item> -</ripple>
\ No newline at end of file + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_activated="true" + android:drawable="@color/drawer_selected_color"/> + <item android:drawable="@drawable/ripple_background" /> +</selector>
\ No newline at end of file diff --git a/res/drawable/ripple_background.xml b/res/drawable/ripple_background.xml new file mode 100644 index 000000000..574dff1c4 --- /dev/null +++ b/res/drawable/ripple_background.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- 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. +--> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="@color/control_highlight_color" />
\ No newline at end of file diff --git a/res/layout/assistant_new_badge.xml b/res/layout/assistant_new_badge.xml deleted file mode 100644 index 21b529722..000000000 --- a/res/layout/assistant_new_badge.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 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. ---> - -<TextView xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/assistant_new_badge" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:paddingLeft="@dimen/nav_new_badge_horizontal_pad" - android:paddingTop="@dimen/nav_new_badge_vertical_pad" - android:paddingRight="@dimen/nav_new_badge_horizontal_pad" - android:paddingBottom="@dimen/nav_new_badge_vertical_pad" - android:background="@drawable/new_badge_background" - android:textSize="@dimen/nav_new_badge_font_size" - android:textStyle="bold" - android:textAllCaps="true" - android:textColor="@android:color/white" - android:text="@string/menu_assistant_new_badge"/>
\ No newline at end of file diff --git a/res/layout/contacts_drawer_activity.xml b/res/layout/contacts_drawer_activity.xml index 814109feb..84e536bef 100644 --- a/res/layout/contacts_drawer_activity.xml +++ b/res/layout/contacts_drawer_activity.xml @@ -17,7 +17,6 @@ <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" @@ -42,15 +41,11 @@ android:background="?android:attr/windowBackground" /> </LinearLayout> - <android.support.design.widget.NavigationView - android:id="@+id/nav_view" - android:theme="@style/NavigationDrawerMenuItemTextAppearance" - android:layout_width="wrap_content" - android:layout_height="match_parent" + <fragment + android:id="@+id/drawer" + android:name="com.android.contacts.drawer.DrawerFragment" android:layout_gravity="start" - android:fitsSystemWindows="true" - app:itemBackground="@drawable/drawer_item_background" - app:headerLayout="@layout/nav_header_main" - app:menu="@menu/activity_main_drawer"/> + android:layout_width="@dimen/drawer_width" + android:layout_height="match_parent" /> </android.support.v4.widget.DrawerLayout> diff --git a/res/layout/drawer_fragment.xml b/res/layout/drawer_fragment.xml new file mode 100644 index 000000000..ea9eed01b --- /dev/null +++ b/res/layout/drawer_fragment.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- 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. +--> + +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true"> + + <android.support.v7.widget.RecyclerView + android:id="@+id/list" + android:background="#FAFAFA" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:divider="@null" /> +</FrameLayout>
\ No newline at end of file diff --git a/res/layout/drawer_header.xml b/res/layout/drawer_header.xml new file mode 100644 index 000000000..1f0151bca --- /dev/null +++ b/res/layout/drawer_header.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- 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. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/label_header" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:orientation="vertical" + android:background="@color/navigation_drawer_background_color"> + + <include layout="@layout/drawer_horizontal_divider" /> + + <FrameLayout + style="@style/DrawerHeaderItemStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:clickable="false"> + + <TextView + android:id="@+id/title" + style="@style/DrawerHeaderTextStyle" + android:layout_height="wrap_content" + android:layout_width="wrap_content"/> + </FrameLayout> +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/drawer_horizontal_divider.xml b/res/layout/drawer_horizontal_divider.xml new file mode 100644 index 000000000..ca096fa7e --- /dev/null +++ b/res/layout/drawer_horizontal_divider.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- 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. +--> + +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="16dp" + android:importantForAccessibility="no"> + + <View + android:id="@+id/divider_top" + android:layout_width="match_parent" + android:layout_height="1dp" + android:layout_gravity="center_vertical" + android:background="@color/drawer_divider_color"/> +</FrameLayout>
\ No newline at end of file diff --git a/res/layout/drawer_item.xml b/res/layout/drawer_item.xml new file mode 100644 index 000000000..f7621a35d --- /dev/null +++ b/res/layout/drawer_item.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- 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. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + style="@style/DrawerItemStyle"> + + <ImageView + android:id="@+id/icon" + style="@style/DrawerItemIconStyle"/> + + <TextView + android:id="@+id/title" + style="@style/DrawerItemTextStyle" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/drawer_primary_item.xml b/res/layout/drawer_primary_item.xml new file mode 100644 index 000000000..cc7bf262c --- /dev/null +++ b/res/layout/drawer_primary_item.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- 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. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + style="@style/DrawerPrimaryItemStyle"> + + <ImageView + android:id="@+id/icon" + style="@style/DrawerItemIconStyle"/> + + <TextView + android:id="@+id/title" + style="@style/DrawerItemTextStyle" /> + + <TextView + android:id="@+id/assistant_new_badge" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical|end" + android:paddingLeft="@dimen/nav_new_badge_horizontal_pad" + android:paddingTop="@dimen/nav_new_badge_vertical_pad" + android:paddingRight="@dimen/nav_new_badge_horizontal_pad" + android:paddingBottom="@dimen/nav_new_badge_vertical_pad" + android:background="@drawable/new_badge_background" + android:textSize="@dimen/nav_new_badge_font_size" + android:textStyle="bold" + android:textAllCaps="true" + android:textColor="@android:color/white" + android:text="@string/menu_assistant_new_badge"/> +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/nav_drawer_spacer b/res/layout/nav_drawer_spacer new file mode 100644 index 000000000..45ecfc4bb --- /dev/null +++ b/res/layout/nav_drawer_spacer @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- 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. +--> + +<View xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/nav_drawer_spacer" + android:layout_width="match_parent" + android:layout_height="@dimen/nav_drawer_spacer_height" + android:background="@drawable/drawer_item_background" + android:importantForAccessibility="no"/>
\ No newline at end of file diff --git a/res/menu/activity_main_drawer.xml b/res/menu/activity_main_drawer.xml deleted file mode 100644 index 07e9802e2..000000000 --- a/res/menu/activity_main_drawer.xml +++ /dev/null @@ -1,61 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- - Copyright (C) 2016 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. - --> - -<menu xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto"> - - <group android:id="@+id/nav_utilities"> - <item - android:id="@+id/nav_all_contacts" - android:icon="@drawable/quantum_ic_account_circle_vd_theme_24" - android:title="@string/contactsList" /> - <item - android:id="@+id/nav_assistant" - app:actionViewClass="android.widget.LinearLayout" - android:icon="@drawable/quantum_ic_assistant_vd_theme_24" - android:title="@string/menu_assistant"/> - </group> - - <group android:id="@+id/groups"> - <item - android:id="@+id/nav_groups" - android:title="@string/menu_title_groups"> - <menu/> - </item> - </group> - - <group android:id="@+id/filters"> - <item - android:id="@+id/nav_filters" - android:title="@string/menu_title_filters"> - <menu/> - </item> - </group> - - <group android:id="@+id/nav_misc"> - <item - android:id="@+id/nav_settings" - android:icon="@drawable/quantum_ic_settings_vd_theme_24" - android:title="@string/menu_settings"/> - <item - android:id="@+id/nav_help" - android:icon="@drawable/quantum_ic_help_vd_theme_24" - android:title="@string/menu_help"/> - </group> - -</menu> diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml index 48f34f246..7753d7d19 100644 --- a/res/values-sw600dp/dimens.xml +++ b/res/values-sw600dp/dimens.xml @@ -59,4 +59,7 @@ <dimen name="floating_action_button_margin_right">32dp</dimen> <!-- Bottom margin of the floating action button --> <dimen name="floating_action_button_margin_bottom">32dp</dimen> + + <!-- Side padding within the navigation drawer --> + <dimen name="drawer_side_padding">24dp</dimen> </resources> diff --git a/res/values/colors.xml b/res/values/colors.xml index d5f2da3b4..e89ed9f83 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -241,4 +241,17 @@ <!-- Background color for sync-off alert. --> <color name="alert_background">#e0e0e0</color> + + <!-- Divider color in navigation drawer --> + <color name="drawer_divider_color">#E5E5E5</color> + + <!-- Background color for the navigation drawer --> + <color name="navigation_drawer_background_color">#FAFAFA</color> + + <!-- Background color for the current selected item in the navigation drawer --> + <color name="drawer_selected_color">#E8E8E8</color> + + <!-- Highlight color used in places such as ripples --> + <color name="control_highlight_color">#1A000000</color> + </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index b33975f62..2c47f3912 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -364,4 +364,19 @@ <!-- Row padding for call subject history items. --> <dimen name="call_subject_history_item_padding">15dp</dimen> + <!-- The width of the drawer --> + <dimen name="drawer_width">320dp</dimen> + <!-- Minimum height of items in navigation drawer --> + <dimen name="drawer_item_fixed_height">48dp</dimen> + <!-- Side padding within the navigation drawer --> + <dimen name="drawer_side_padding">16dp</dimen> + <!-- Size of the icon in navigation drawer --> + <dimen name="drawer_item_icon_size">32dp</dimen> + <!-- The side margin of the item text in navigation drawer --> + <dimen name="drawer_item_text_margin">32dp</dimen> + <!-- The height of the spacer in navigation drawer --> + <dimen name="nav_drawer_spacer_height">8dp</dimen> + <!-- Side padding within the navigation drawer --> + <dimen name="drawer_label_header_end_padding">24dp</dimen> + </resources> diff --git a/res/values/ids.xml b/res/values/ids.xml index 0808496a9..a4b8b4b0f 100644 --- a/res/values/ids.xml +++ b/res/values/ids.xml @@ -47,11 +47,32 @@ <!-- Menu group ID for settings and help & feedback --> <item type="id" name="nav_misc" /> - <!-- Menu group ID for the contact groups --> - <item type="id" name="nav_groups_items" /> + <!-- Menu ID for Contacts menu --> + <item type="id" name="nav_all_contacts" /> - <!-- Menu group ID for the contact filters --> - <item type="id" name="nav_filters_items" /> + <!-- Menu ID for Suggestions menu --> + <item type="id" name="nav_assistant" /> + + <!-- Menu ID for group header --> + <item type="id" name="nav_groups" /> + + <!-- Menu ID for each group menu item --> + <item type="id" name="nav_group" /> + + <!-- Menu ID for create label menu item --> + <item type="id" name="nav_create_label" /> + + <!-- Menu ID for filter header --> + <item type="id" name="nav_filters" /> + + <!-- Menu ID for each filter menu item --> + <item type="id" name="nav_filter" /> + + <!-- Menu ID for Settings menu --> + <item type="id" name="nav_settings" /> + + <!-- Menu ID for help & feedback menu --> + <item type="id" name="nav_help" /> <!-- For vcard.ImportVCardActivity --> <item type="id" name="dialog_cache_vcard"/> diff --git a/res/values/strings.xml b/res/values/strings.xml index 053d0e371..488a1dbc9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -709,6 +709,9 @@ <!-- Close drawer content descriptions [CHAR LIMIT=40] --> <string name="navigation_drawer_close">Close navigation drawer</string> + <!-- Content description of label name in navigation drawer. For example: Coworker Label, Friends Label [CHAR LIMIT=30] --> + <string name="navigation_drawer_label"><xliff:g id="label_name">%s</xliff:g> label</string> + <!-- Menu section title of "labels" [CHAR LIMIT=20] --> <string name="menu_title_groups">Labels</string> diff --git a/res/values/styles.xml b/res/values/styles.xml index a1875cae7..50971b01f 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -13,7 +13,8 @@ See the License for the specific language governing permissions and limitations under the License. --> -<resources> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools"> <style name="EditorActivityTheme" parent="@style/PeopleActivityTheme"> <item name="actionBarStyle">@style/EditorActionBarStyle</item> @@ -515,4 +516,74 @@ background and text color. See also android:style/Widget.Holo.TextView.ListSepar <item name="android:windowIsTranslucent">true</item> <item name="android:statusBarColor">@color/contextual_selection_bar_status_bar_color</item> </style> + + <!-- Style for item in navigation drawer --> + <style name="DrawerItemStyle"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">@dimen/drawer_item_fixed_height</item> + <item name="android:layout_gravity">center_vertical</item> + <item name="android:background">@drawable/drawer_item_background</item> + <item name="android:orientation">horizontal</item> + <item name="android:paddingStart">@dimen/drawer_side_padding</item> + </style> + + <style name="DrawerPrimaryItemStyle" parent="DrawerItemStyle"> + <item name="android:paddingEnd">@dimen/drawer_item_text_margin</item> + </style> + + <!-- Style for item icon in navigation drawer --> + <style name="DrawerItemIconStyle"> + <item name="android:layout_width">@dimen/drawer_item_icon_size</item> + <item name="android:layout_height">@dimen/drawer_item_icon_size</item> + <item name="android:layout_gravity">center</item> + <item name="android:gravity">center</item> + <item name="android:scaleType">center</item> + </style> + + <!-- Style for primary item text in navigation drawer --> + <style name="DrawerItemTextStyle" parent="DrawerTextStyle"> + <item name="android:textColor">@color/primary_text_color</item> + <item name="android:layout_width">0dip</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_weight">1</item> + <item name="android:layout_marginStart">@dimen/drawer_item_text_margin</item> + <item name="android:layout_marginEnd">@dimen/drawer_item_text_margin</item> + </style> + + <style name="DrawerTextStyle"> + <item name="android:fontFamily" tools:ignore="NewApi">sans-serif-medium</item> + <item name="android:gravity">center_vertical</item> + <item name="android:layout_gravity">center_vertical</item> + <item name="android:textSize">14sp</item> + <item name="android:singleLine">true</item> + <item name="android:ellipsize">end</item> + </style> + + <style name="DrawerItemTextActiveStyle"> + <item name="android:textColor">@color/primary_color</item> + <item name="android:textStyle">bold</item> + </style> + + <style name="DrawerItemTextInactiveStyle"> + <item name="android:textColor">@color/quantum_black_text</item> + <item name="android:textStyle">bold</item> + </style> + + <style name="DrawerHeaderTextStyle" parent="DrawerTextStyle"> + <item name="android:layout_gravity">center_vertical|start</item> + <item name="android:paddingTop">12dp</item> + <item name="android:paddingBottom">12dp</item> + <item name="android:textColor">@color/quantum_black_secondary_text</item> + <item name="android:textSize">14sp</item> + </style> + + <style name="DrawerBadgeStyle" parent="DrawerHeaderTextStyle"> + <item name="android:layout_gravity">center_vertical|end</item> + </style> + + <style name="DrawerHeaderItemStyle"> + <item name="android:paddingStart">@dimen/drawer_side_padding</item> + <item name="android:paddingEnd">@dimen/drawer_label_header_end_padding</item> + </style> + </resources> diff --git a/src-bind/com/android/contactsbind/ObjectFactory.java b/src-bind/com/android/contactsbind/ObjectFactory.java index 5fbab3eea..e8b9cebb1 100644 --- a/src-bind/com/android/contactsbind/ObjectFactory.java +++ b/src-bind/com/android/contactsbind/ObjectFactory.java @@ -41,4 +41,8 @@ public class ObjectFactory { public static Intent getContactSheetIntent(Context context, Uri contactLookupUri) { return null; } + + public static Uri getWelcomeUri() { + return null; + } } diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java index bec2addd6..d6e9642c0 100644 --- a/src/com/android/contacts/activities/PeopleActivity.java +++ b/src/com/android/contacts/activities/PeopleActivity.java @@ -29,7 +29,6 @@ import android.content.IntentFilter; import android.content.SyncStatusObserver; import android.content.res.Configuration; import android.graphics.Color; -import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -37,45 +36,37 @@ import android.provider.ContactsContract; import android.provider.ContactsContract.Intents; import android.provider.ContactsContract.ProviderStatus; import android.support.annotation.LayoutRes; -import android.support.annotation.NonNull; import android.support.design.widget.CoordinatorLayout; -import android.support.design.widget.NavigationView; import android.support.design.widget.Snackbar; import android.support.v4.content.ContextCompat; import android.support.v4.content.LocalBroadcastManager; import android.support.v4.view.GravityCompat; -import android.support.v4.view.MenuItemCompat; import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; -import android.view.Gravity; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.SubMenu; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.TextView; import android.widget.Toast; import com.android.contacts.AppCompatContactsActivity; import com.android.contacts.ContactSaveService; import com.android.contacts.R; import com.android.contacts.compat.CompatUtils; +import com.android.contacts.drawer.DrawerFragment; +import com.android.contacts.drawer.DrawerFragment.DrawerFragmentListener; import com.android.contacts.editor.ContactEditorFragment; import com.android.contacts.editor.SelectAccountDialogFragment; import com.android.contacts.group.GroupListItem; import com.android.contacts.group.GroupMembersFragment; -import com.android.contacts.group.GroupMetaData; import com.android.contacts.group.GroupNameEditDialogFragment; import com.android.contacts.group.GroupUtil; import com.android.contacts.group.GroupsFragment; @@ -96,8 +87,6 @@ import com.android.contacts.list.ProviderStatusWatcher.ProviderStatusListener; import com.android.contacts.logging.Logger; import com.android.contacts.logging.ScreenEvent.ScreenType; import com.android.contacts.model.AccountTypeManager; -import com.android.contacts.model.account.AccountDisplayInfo; -import com.android.contacts.model.account.AccountDisplayInfoFactory; import com.android.contacts.model.account.AccountInfo; import com.android.contacts.model.account.AccountWithDataSet; import com.android.contacts.preference.ContactsPreferenceActivity; @@ -115,19 +104,14 @@ import com.android.contactsbind.ObjectFactory; import com.google.common.util.concurrent.Futures; import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** * Displays a list to browse contacts. */ public class PeopleActivity extends AppCompatContactsActivity implements - AccountFiltersListener, - GroupsListener, - NavigationView.OnNavigationItemSelectedListener, + DrawerFragmentListener, SelectAccountDialogFragment.Listener { /** Possible views of Contacts app. */ @@ -143,8 +127,6 @@ public class PeopleActivity extends AppCompatContactsActivity implements private static final String TAG_ALL = "contacts-all"; private static final String TAG_UNAVAILABLE = "contacts-unavailable"; private static final String TAG_GROUP_VIEW = "contacts-groups"; - private static final String TAG_GROUPS = "groups"; - private static final String TAG_FILTERS = "filters"; private static final String TAG_SELECT_ACCOUNT_DIALOG = "selectAccountDialog"; private static final String TAG_GROUP_NAME_EDIT_DIALOG = "groupNameEditDialog"; @@ -198,26 +180,17 @@ public class PeopleActivity extends AppCompatContactsActivity implements private final int mInstanceId; private static final AtomicInteger sNextInstanceId = new AtomicInteger(); - /** Navigation drawer related */ private ContactListFilterController mContactListFilterController; + + /** Navigation drawer related */ private DrawerLayout mDrawerLayout; + private DrawerFragment mDrawerFragment; private ContactsActionBarDrawerToggle mToggle; private Toolbar mToolbar; - private NavigationView mNavigationView; // The account the new group will be created under. private AccountWithDataSet mNewGroupAccount; - // Recycle badge if possible - private TextView mAssistantNewBadge; - - // Checkable menu item lookup maps. Every map declared here should be added to - // clearCheckedMenus() so that they can be cleared. - // TODO find a better way to handle selected menu item state, when switching to fragments. - private Map<Long, MenuItem> mGroupMenuMap = new HashMap<>(); - private Map<ContactListFilter, MenuItem> mFilterMenuMap = new HashMap<>(); - private Map<Integer, MenuItem> mIdMenuMap = new HashMap<>(); - private Object mStatusChangeListenerHandle; private final Handler mHandler = new Handler(); @@ -283,7 +256,7 @@ public class PeopleActivity extends AppCompatContactsActivity implements private final ProviderStatusListener mProviderStatusListener = new ProviderStatusListener() { @Override public void onProviderStatusChange() { - reloadGroupsAndFiltersIfNeeded(); + // TODO see if it works with drawer fragment. updateViewConfiguration(false); } }; @@ -349,7 +322,6 @@ public class PeopleActivity extends AppCompatContactsActivity implements if (newState != DrawerLayout.STATE_IDLE) { updateStatusBarBackground(); } - initializeAssistantNewBadge(); } } @@ -401,9 +373,9 @@ public class PeopleActivity extends AppCompatContactsActivity implements // Set up hamburger button. mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); + mDrawerFragment = (DrawerFragment) getFragmentManager().findFragmentById(R.id.drawer); mToggle = new ContactsActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); - mDrawerLayout.setDrawerListener(mToggle); // Set fallback handler for when drawer is disabled. mToggle.setToolbarNavigationClickListener(new View.OnClickListener() { @@ -420,14 +392,6 @@ public class PeopleActivity extends AppCompatContactsActivity implements mCurrentView = ContactsView.ALL_CONTACTS; } - // Set up hamburger menu items. - mNavigationView = (NavigationView) findViewById(R.id.nav_view); - mNavigationView.setNavigationItemSelectedListener(this); - setUpMenu(); - - initializeAssistantNewBadge(); - loadGroupsAndFilters(); - if (savedState != null && savedState.containsKey(KEY_NEW_GROUP_ACCOUNT)) { mNewGroupAccount = AccountWithDataSet.unstringify( savedState.getString(KEY_NEW_GROUP_ACCOUNT)); @@ -450,33 +414,6 @@ public class PeopleActivity extends AppCompatContactsActivity implements getWindow().setBackgroundDrawable(null); } - private void loadGroupsAndFilters() { - final FragmentManager fragmentManager = getFragmentManager(); - final FragmentTransaction transaction = fragmentManager.beginTransaction(); - addGroupsAndFiltersFragments(transaction); - transaction.commitAllowingStateLoss(); - fragmentManager.executePendingTransactions(); - } - - private void addGroupsAndFiltersFragments(FragmentTransaction transaction) { - final FragmentManager fragmentManager = getFragmentManager(); - GroupsFragment groupsFragment = - (GroupsFragment) fragmentManager.findFragmentByTag(TAG_GROUPS); - if (groupsFragment == null) { - groupsFragment = new GroupsFragment(); - transaction.add(groupsFragment, TAG_GROUPS); - } - groupsFragment.setListener(this); - - AccountFiltersFragment accountFiltersFragment = - (AccountFiltersFragment) fragmentManager.findFragmentByTag(TAG_FILTERS); - if (accountFiltersFragment == null) { - accountFiltersFragment = new AccountFiltersFragment(); - transaction.add(accountFiltersFragment, TAG_FILTERS); - } - accountFiltersFragment.setListener(this); - } - @Override protected void onNewIntent(Intent intent) { final String action = intent.getAction(); @@ -761,20 +698,6 @@ public class PeopleActivity extends AppCompatContactsActivity implements } } - private void reloadGroupsAndFiltersIfNeeded() { - final int providerStatus = mProviderStatusWatcher.getProviderStatus(); - final Menu menu = mNavigationView.getMenu(); - final MenuItem groupsMenuItem = menu.findItem(R.id.nav_groups); - final SubMenu subMenu = groupsMenuItem.getSubMenu(); - - // Reload groups and filters if provider status changes to "normal" and there's no groups - // loaded or just a "Create new..." menu item is in the menu. - if (subMenu != null && subMenu.size() <= 1 && providerStatus == ProviderStatus.STATUS_NORMAL - && !mProviderStatus.equals(providerStatus)) { - loadGroupsAndFilters(); - } - } - private void updateViewConfiguration(boolean forceUpdate) { int providerStatus = mProviderStatusWatcher.getProviderStatus(); if (!forceUpdate && (mProviderStatus != null) @@ -858,7 +781,7 @@ public class PeopleActivity extends AppCompatContactsActivity implements // Handle the back event in drawer first. if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) { - mDrawerLayout.closeDrawer(GravityCompat.START); + closeDrawer(); return; } @@ -1010,7 +933,7 @@ public class PeopleActivity extends AppCompatContactsActivity implements } } - private void onGroupMenuItemClicked(long groupId, String title) { + private void onGroupMenuItemClicked(long groupId) { if (isGroupView() && mMembersFragment != null && mMembersFragment.isCurrentGroup(groupId)) { return; @@ -1083,15 +1006,10 @@ public class PeopleActivity extends AppCompatContactsActivity implements } mShouldSwitchToAllContacts = false; mCurrentView = ContactsView.ALL_CONTACTS; + mDrawerFragment.setNavigationItemChecked(ContactsView.ALL_CONTACTS); showFabWithAnimation(/* showFab */ true); mContactsListFragment.scrollToTop(); - resetFilter(); - - final Menu menu = mNavigationView.getMenu(); - final MenuItem allContacts = menu.findItem(R.id.nav_all_contacts); - updateMenuSelection(allContacts); - setTitle(getString(R.string.contactsList)); } @@ -1130,10 +1048,6 @@ public class PeopleActivity extends AppCompatContactsActivity implements return mMembersFragment; } - protected GroupMetaData getGroupMetaData() { - return mMembersFragment == null ? null : mMembersFragment.getGroupMetaData(); - } - private void handleFilterChangeForFragment(ContactListFilter filter) { if (mContactsListFragment.canSetActionBar()) { mContactsListFragment.setFilterAndUpdateTitle(filter); @@ -1151,9 +1065,6 @@ public class PeopleActivity extends AppCompatContactsActivity implements mShouldSwitchToAllContacts = true; } - // Check menu in navigation drawer. - updateFilterMenu(filter); - if (CompatUtils.isNCompatible()) { getWindow().getDecorView() .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); @@ -1161,26 +1072,9 @@ public class PeopleActivity extends AppCompatContactsActivity implements invalidateOptionsMenu(); } - private void initializeAssistantNewBadge() { - if (mNavigationView == null) { - return; - } - final MenuItem assistantMenu = mNavigationView.getMenu().findItem(R.id.nav_assistant); - if (assistantMenu == null) { - return; - } - final LinearLayout newBadgeFrame = - (LinearLayout) MenuItemCompat.getActionView(assistantMenu); - final boolean showWelcomeBadge = !SharedPreferenceUtil.isWelcomeCardDismissed(this); - if (showWelcomeBadge && newBadgeFrame.getChildCount() == 0) { - if (mAssistantNewBadge == null) { - mAssistantNewBadge = (TextView) LayoutInflater.from(this) - .inflate(R.layout.assistant_new_badge, null); - } - newBadgeFrame.setGravity(Gravity.CENTER_VERTICAL); - newBadgeFrame.addView(mAssistantNewBadge); - } else if (!showWelcomeBadge && newBadgeFrame.getChildCount() > 0) { - newBadgeFrame.removeAllViews(); + public void updateDrawerGroupMenu(long groupId) { + if (mDrawerFragment != null) { + mDrawerFragment.updateGroupMenu(groupId); } } @@ -1200,31 +1094,6 @@ public class PeopleActivity extends AppCompatContactsActivity implements } } - private void setUpMenu() { - final Menu menu = mNavigationView.getMenu(); - - if (ObjectFactory.getAssistantFragment() == null) { - menu.removeItem(R.id.nav_assistant); - } else { - final int id = R.id.nav_assistant; - final MenuItem assistantMenu = menu.findItem(id); - mIdMenuMap.put(id, assistantMenu); - if (isAssistantView()) { - updateMenuSelection(assistantMenu); - } - } - - if (!HelpUtils.isHelpAndFeedbackAvailable()) { - menu.removeItem(R.id.nav_help); - } - - final MenuItem allContactsMenu = menu.findItem(R.id.nav_all_contacts); - mIdMenuMap.put(R.id.nav_all_contacts, allContactsMenu); - if (isAllContactsView()) { - updateMenuSelection(allContactsMenu); - } - } - public Toolbar getToolbar() { return mToolbar; } @@ -1241,90 +1110,6 @@ public class PeopleActivity extends AppCompatContactsActivity implements mToggle.onConfigurationChanged(newConfig); } - @Override - public void onGroupsLoaded(List<GroupListItem> groupListItems, - boolean areGroupWritableAccountsAvailable) { - final Menu menu = mNavigationView.getMenu(); - final MenuItem groupsMenuItem = menu.findItem(R.id.nav_groups); - final SubMenu subMenu = groupsMenuItem.getSubMenu(); - subMenu.removeGroup(R.id.nav_groups_items); - mGroupMenuMap = new HashMap<>(); - - final GroupMetaData groupMetaData = getGroupMetaData(); - - if (groupListItems != null) { - // Add each group - for (final GroupListItem groupListItem : groupListItems) { - if (GroupUtil.isEmptyFFCGroup(groupListItem)) { - continue; - } - final String title = groupListItem.getTitle(); - final MenuItem menuItem = - subMenu.add(R.id.nav_groups_items, Menu.NONE, Menu.NONE, title); - mGroupMenuMap.put(groupListItem.getGroupId(), menuItem); - if (isGroupView() && groupMetaData != null - && groupMetaData.groupId == groupListItem.getGroupId()) { - updateMenuSelection(menuItem); - } - menuItem.setIcon(R.drawable.quantum_ic_label_vd_theme_24); - menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - onGroupMenuItemClicked(groupListItem.getGroupId(), - groupListItem.getTitle()); - updateMenuSelection(menuItem); - mDrawerLayout.closeDrawer(GravityCompat.START); - return true; - } - }); - - updateMenuContentDescription(menuItem, - getString(R.string.group_edit_field_hint_text)); - } - } - - // Don't show "Create label" menu if there's no group-writable accounts available. - if (!areGroupWritableAccountsAvailable) { - return; - } - - // Create a menu item in the sub menu to add new groups - final MenuItem menuItem = subMenu.add(R.id.nav_groups_items, Menu.NONE, - Menu.NONE, getString(R.string.menu_new_group_action_bar)); - menuItem.setIcon(R.drawable.quantum_ic_add_vd_theme_24); - menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - onCreateGroupMenuItemClicked(); - mDrawerLayout.closeDrawer(GravityCompat.START); - return true; - } - }); - - if (isGroupView() && groupMetaData != null) { - updateGroupMenu(groupMetaData); - } - } - - public void updateGroupMenu(GroupMetaData groupMetaData) { - clearCheckedMenus(); - if (groupMetaData != null && mGroupMenuMap != null - && mGroupMenuMap.get(groupMetaData.groupId) != null) { - setMenuChecked(mGroupMenuMap.get(groupMetaData.groupId), true); - } - } - - private void updateMenuContentDescription(MenuItem menuItem, CharSequence contentDescription) { - // Create a dummy action view to attach extra hidden content description to the menuItem - // for Talkback. We want Talkback to read out the account type but not have it be part - // of the menuItem title. - final LinearLayout view = (LinearLayout) LayoutInflater.from(this) - .inflate(R.layout.menu_item_action_view, null); - view.setContentDescription(contentDescription); - view.setVisibility(View.VISIBLE); - menuItem.setActionView(view); - } - protected void onCreateGroupMenuItemClicked() { // Select the account to create the group final Bundle extras = getIntent().getExtras(); @@ -1362,6 +1147,7 @@ public class PeopleActivity extends AppCompatContactsActivity implements TAG_SELECT_ACCOUNT_DIALOG); } + // Implementation of SelectAccountDialogFragment.Listener @Override public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) { mNewGroupAccount = account; @@ -1374,90 +1160,53 @@ public class PeopleActivity extends AppCompatContactsActivity implements public void onAccountSelectorCancelled() { } + // Implementation of DrawerFragmentListener @Override - public void onFiltersLoaded(List<ContactListFilter> accountFilterItems) { - final AccountDisplayInfoFactory accountDisplayFactory = AccountDisplayInfoFactory. - fromListFilters(this, accountFilterItems); - - final Menu menu = mNavigationView.getMenu(); - final MenuItem filtersMenuItem = menu.findItem(R.id.nav_filters); - final SubMenu subMenu = filtersMenuItem.getSubMenu(); - subMenu.removeGroup(R.id.nav_filters_items); - mFilterMenuMap = new HashMap<>(); - - if (accountFilterItems == null || accountFilterItems.size() < 2) { - return; - } - - for (int i = 0; i < accountFilterItems.size(); i++) { - final ContactListFilter filter = accountFilterItems.get(i); - final AccountDisplayInfo displayableAccount = - accountDisplayFactory.getAccountDisplayInfoFor(filter); - final CharSequence menuName = displayableAccount.getNameLabel(); - final MenuItem menuItem = subMenu.add(R.id.nav_filters_items, Menu.NONE, - Menu.NONE, menuName); - if (isAccountView() && filter == mContactListFilterController.getFilter()) { - updateMenuSelection(menuItem); - } - mFilterMenuMap.put(filter, menuItem); - final Intent intent = new Intent(); - intent.putExtra(AccountFilterActivity.EXTRA_CONTACT_LIST_FILTER, filter); - menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - onFilterMenuItemClicked(intent); - updateMenuSelection(menuItem); - mDrawerLayout.closeDrawer(GravityCompat.START); - return true; - } - }); - if (displayableAccount.getIcon() != null) { - menuItem.setIcon(displayableAccount.getIcon()); - // Get rid of the default menu item overlay and show original account icons. - menuItem.getIcon().setColorFilter(Color.TRANSPARENT, PorterDuff.Mode.SRC_ATOP); - } + public void onDrawerItemClicked(){ + closeDrawer(); + } - updateMenuContentDescription(menuItem, displayableAccount.getTypeLabel()); + @Override + public void onContactsViewSelected(ContactsView mode) { + if (mode == ContactsView.ALL_CONTACTS) { + switchToAllContacts(); + } else if (mode == ContactsView.ASSISTANT) { + launchAssistant(); + } else { + throw new IllegalStateException("Unknown view " + mode); } + } - if (isAccountView()) { - updateFilterMenu(mContactListFilterController.getFilter()); - } + @Override + public void onCreateLabelButtonClicked() { + onCreateGroupMenuItemClicked(); } - public void updateFilterMenu(ContactListFilter filter) { - clearCheckedMenus(); - if (filter != null && filter.isContactsFilterType()) { - if (mIdMenuMap != null && mIdMenuMap.get(R.id.nav_all_contacts) != null) { - setMenuChecked(mIdMenuMap.get(R.id.nav_all_contacts), true); - } - } else { - if (mFilterMenuMap != null && mFilterMenuMap.get(filter) != null) { - setMenuChecked(mFilterMenuMap.get(filter), true); + @Override + public void onOpenSettings() { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + startActivity(createPreferenceIntent()); } - } + }, DRAWER_CLOSE_DELAY); } - private void clearCheckedMenus() { - clearCheckedMenu(mFilterMenuMap); - clearCheckedMenu(mGroupMenuMap); - clearCheckedMenu(mIdMenuMap); + @Override + public void onLaunchHelpFeedback() { + HelpUtils.launchHelpAndFeedbackForMainScreen(this); } - private void clearCheckedMenu(Map<?, MenuItem> map) { - final Iterator it = map.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry pair = (Map.Entry) it.next(); - setMenuChecked(map.get(pair.getKey()), false); - } + @Override + public void onGroupViewSelected(GroupListItem groupListItem) { + onGroupMenuItemClicked(groupListItem.getGroupId()); } - private void setMenuChecked(MenuItem menuItem, boolean checked) { - if (menuItem == null) { - return; - } - menuItem.setCheckable(checked); - menuItem.setChecked(checked); + @Override + public void onAccountViewSelected(ContactListFilter filter) { + final Intent intent = new Intent(); + intent.putExtra(AccountFilterActivity.EXTRA_CONTACT_LIST_FILTER, filter); + onFilterMenuItemClicked(intent); } public boolean isGroupView() { @@ -1480,39 +1229,8 @@ public class PeopleActivity extends AppCompatContactsActivity implements return isGroupView() || isAssistantView(); } - @Override - public boolean onNavigationItemSelected(@NonNull final MenuItem item) { - final int id = item.getItemId(); - - if (id == R.id.nav_settings) { - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - startActivity(createPreferenceIntent()); - } - }, DRAWER_CLOSE_DELAY); - } else if (id == R.id.nav_help) { - HelpUtils.launchHelpAndFeedbackForMainScreen(this); - } else if (id == R.id.nav_all_contacts) { - switchToAllContacts(); - } else if (id == R.id.nav_assistant) { - if (!isAssistantView()) { - launchAssistant(); - updateMenuSelection(item); - } - } else if (item.getIntent() != null) { - ImplicitIntentsUtil.startActivityInApp(this, item.getIntent()); - } else { - Log.w(TAG, "Unhandled navigation view item selection"); - } - + public void closeDrawer() { mDrawerLayout.closeDrawer(GravityCompat.START); - return true; - } - - private void updateMenuSelection(MenuItem menuItem) { - clearCheckedMenus(); - setMenuChecked(menuItem, true); } private Intent createPreferenceIntent() { diff --git a/src/com/android/contacts/drawer/DrawerAdapter.java b/src/com/android/contacts/drawer/DrawerAdapter.java new file mode 100644 index 000000000..959d478bc --- /dev/null +++ b/src/com/android/contacts/drawer/DrawerAdapter.java @@ -0,0 +1,466 @@ +/* + * 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.support.annotation.LayoutRes; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +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.util.SharedPreferenceUtil; + +import java.util.ArrayList; +import java.util.List; + +public class DrawerAdapter extends RecyclerView.Adapter { + + 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 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 in the getItem() method. The ordering is based on: + // [Navigation spacer item] + // [Primary items] (Contacts, Suggestions) + // [Group Header] + // [Groups] + // [Create Label button] + // [Account Header] + // [Accounts] + // [Misc items] (a divider, Settings, Help & Feedback) + // [Navigation spacer item] + private NavSpacerItem mNavSpacerItem = 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 List<BaseDrawerItem> mMiscItems = new ArrayList<>(); + + private List<BaseDrawerItem> mItemsList = new ArrayList<>(); + private OnClickListener mListener; + 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); + // 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)); + 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); + // 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)); + 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); + mItemsList.addAll(mPrimaryItems); + if (mAreGroupWritableAccountsAvailable) { + mItemsList.add(mGroupHeader); + } + mItemsList.addAll(mGroupEntries); + if (mAreGroupWritableAccountsAvailable) { + mItemsList.add(mCreateLabelButton); + } + if (mAccountEntries.size() > 0) { + mItemsList.add(mAccountHeader); + } + mItemsList.addAll(mAccountEntries); + mItemsList.addAll(mMiscItems); + mItemsList.add(mNavSpacerItem); + } + + public void setItemOnClickListener(OnClickListener listener) { + mListener = listener; + } + + 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 getItemCount() { + 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 getItemViewType(int position) { + return getItem(position).viewType; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + switch (viewType) { + case VIEW_TYPE_NAV_SPACER: + return getBaseViewHolder(R.layout.nav_drawer_spacer, parent); + case VIEW_TYPE_PRIMARY_ITEM: + return getPrimaryItemView(parent); + case VIEW_TYPE_HEADER_ITEM: + return getHeaderItemViewHolder(parent); + case VIEW_TYPE_GROUP_ENTRY: + case VIEW_TYPE_CREATE_LABEL: + case VIEW_TYPE_ACCOUNT_ENTRY: + case VIEW_TYPE_MISC_ITEM: + return getDrawerItemViewHolder(parent); + case VIEW_TYPE_NAV_DIVIDER: + return getBaseViewHolder(R.layout.drawer_horizontal_divider, parent); + } + throw new IllegalStateException("Unknown view type " + viewType); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + final BaseDrawerItem item = getItem(position); + switch (item.viewType) { + case VIEW_TYPE_PRIMARY_ITEM: + bindPrimaryItemViewHolder((PrimaryItemViewHolder) holder, (PrimaryItem) item); + break; + case VIEW_TYPE_HEADER_ITEM: + bindHeaderItemViewHolder((HeaderItemViewHolder) holder, (HeaderItem) item); + break; + case VIEW_TYPE_GROUP_ENTRY: + bindGroupItemViewHolder((DrawerItemViewHolder) holder, (GroupEntryItem) item); + break; + case VIEW_TYPE_ACCOUNT_ENTRY: + bindAccountViewHolder((DrawerItemViewHolder) holder, (AccountEntryItem) item); + break; + case VIEW_TYPE_CREATE_LABEL: + case VIEW_TYPE_MISC_ITEM: + bindDrawerItemViewHolder((DrawerItemViewHolder) holder, item); + break; + } + } + + private void bindPrimaryItemViewHolder(PrimaryItemViewHolder viewHolder, PrimaryItem item) { + viewHolder.titleView.setText(item.text); + viewHolder.iconView.setImageResource(item.icon); + viewHolder.itemView.setId(item.id); + viewHolder.itemView.setOnClickListener(mListener); + final boolean showWelcomeBadge = !SharedPreferenceUtil.isWelcomeCardDismissed(mActivity); + if (item.contactsView == ContactsView.ASSISTANT && showWelcomeBadge) { + viewHolder.newBadge.setVisibility(View.VISIBLE); + } else { + viewHolder.newBadge.setVisibility(View.GONE); + } + viewHolder.itemView.setActivated(item.contactsView == mSelectedView); + updateSelectedStatus(viewHolder); + } + + private void bindHeaderItemViewHolder(HeaderItemViewHolder viewHolder, HeaderItem item) { + viewHolder.titleView.setText(item.text); + viewHolder.itemView.setId(item.id); + } + + private void bindGroupItemViewHolder(DrawerItemViewHolder viewHolder, GroupEntryItem item) { + final GroupListItem group = item.group; + viewHolder.titleView.setText(group.getTitle()); + viewHolder.iconView.setImageResource(R.drawable.quantum_ic_label_vd_theme_24); + viewHolder.itemView.setId(item.id); + viewHolder.itemView.setTag(group); + viewHolder.itemView.setOnClickListener(mListener); + viewHolder.itemView.setContentDescription( + mActivity.getString(R.string.navigation_drawer_label, group.getTitle())); + viewHolder.itemView.setActivated(group.getGroupId() == mSelectedGroupId + && mSelectedView == ContactsView.GROUP_VIEW); + updateSelectedStatus(viewHolder); + } + + private void bindAccountViewHolder(DrawerItemViewHolder viewHolder, AccountEntryItem item) { + final ContactListFilter account = item.account; + viewHolder.titleView.setText(account.accountName); + final AccountDisplayInfo displayableAccount = + mAccountDisplayFactory.getAccountDisplayInfoFor(item.account); + viewHolder.iconView.setImageDrawable(displayableAccount.getIcon()); + viewHolder.iconView.setScaleType(ImageView.ScaleType.FIT_CENTER); + viewHolder.itemView.setId(item.id); + viewHolder.itemView.setTag(account); + viewHolder.itemView.setOnClickListener(mListener); + viewHolder.itemView.setContentDescription( + displayableAccount.getTypeLabel() + " " + account.accountName); + viewHolder.itemView.setActivated(account.equals(mSelectedAccount) + && mSelectedView == ContactsView.ACCOUNT_VIEW); + updateSelectedStatus(viewHolder); + viewHolder.iconView.clearColorFilter(); + } + + private void bindDrawerItemViewHolder(DrawerItemViewHolder viewHolder, BaseDrawerItem item) { + viewHolder.titleView.setText(item.text); + viewHolder.iconView.setImageResource(item.icon); + viewHolder.itemView.setId(item.id); + viewHolder.itemView.setOnClickListener(mListener); + viewHolder.itemView.setActivated(false); + updateSelectedStatus(viewHolder); + } + + private void updateSelectedStatus(DrawerItemViewHolder viewHolder) { + final boolean activated = viewHolder.itemView.isActivated(); + viewHolder.titleView.setTextAppearance(mActivity, activated + ? TYPEFACE_STYLE_ACTIVATE : TYPEFACE_STYLE_INACTIVE); + if (activated) { + viewHolder.iconView.setColorFilter(mActivity.getResources().getColor(R.color + .primary_color), PorterDuff.Mode.SRC_ATOP); + } else { + viewHolder.iconView.clearColorFilter(); + } + } + + private BaseViewHolder getBaseViewHolder(@LayoutRes int layoutResID, ViewGroup parent) { + final View view = mInflater.inflate(layoutResID, parent, false); + return new BaseViewHolder(view); + } + + private HeaderItemViewHolder getHeaderItemViewHolder(ViewGroup parent) { + final View view = mInflater.inflate(R.layout.drawer_header, parent, false); + return new HeaderItemViewHolder(view); + } + + private DrawerItemViewHolder getDrawerItemViewHolder(ViewGroup parent) { + final View view = mInflater.inflate(R.layout.drawer_item, parent, false); + return new DrawerItemViewHolder(view); + } + + private PrimaryItemViewHolder getPrimaryItemView(ViewGroup parent) { + final View view = mInflater.inflate(R.layout.drawer_primary_item, parent, false); + return new PrimaryItemViewHolder(view); + } + + private void notifyChangeAndRebuildList() { + notifyDataSetChanged(); + rebuildItemsList(); + } + + 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 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; + } + } + + /** + * ViewHolder classes + */ + public static class BaseViewHolder extends RecyclerView.ViewHolder { + public BaseViewHolder(View itemView) { + super(itemView); + } + } + + public static class HeaderItemViewHolder extends BaseViewHolder { + public final TextView titleView; + + public HeaderItemViewHolder(View itemView) { + super(itemView); + titleView = (TextView) itemView.findViewById(R.id.title); + } + } + + public class DrawerItemViewHolder extends HeaderItemViewHolder { + public final ImageView iconView; + + public DrawerItemViewHolder(View itemView) { + super(itemView); + iconView = (ImageView) itemView.findViewById(R.id.icon); + } + } + + public class PrimaryItemViewHolder extends DrawerItemViewHolder { + public final TextView newBadge; + + public PrimaryItemViewHolder(View itemView) { + super(itemView); + newBadge = (TextView) itemView.findViewById(R.id.assistant_new_badge); + } + } +} diff --git a/src/com/android/contacts/drawer/DrawerFragment.java b/src/com/android/contacts/drawer/DrawerFragment.java new file mode 100644 index 000000000..b57f1514f --- /dev/null +++ b/src/com/android/contacts/drawer/DrawerFragment.java @@ -0,0 +1,249 @@ +/* + * 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.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.android.contacts.R; +import com.android.contacts.activities.PeopleActivity.ContactsView; +import com.android.contacts.group.GroupListItem; +import com.android.contacts.group.GroupUtil; +import com.android.contacts.group.GroupsFragment; +import com.android.contacts.group.GroupsFragment.GroupsListener; +import com.android.contacts.interactions.AccountFiltersFragment; +import com.android.contacts.interactions.AccountFiltersFragment.AccountFiltersListener; +import com.android.contacts.list.ContactListFilter; +import com.android.contactsbind.ObjectFactory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class DrawerFragment extends Fragment implements AccountFiltersListener, GroupsListener { + + private WelcomeContentObserver mObserver; + private RecyclerView mDrawerRecyclerView; + private DrawerAdapter mDrawerAdapter; + private ContactsView mCurrentContactsView; + private DrawerFragmentListener mListener; + private GroupsFragment mGroupsFragment; + private AccountFiltersFragment mAccountFiltersFragment; + + private static final String TAG_GROUPS = "groups"; + private static final String TAG_FILTERS = "filters"; + private static final String KEY_CONTACTS_VIEW = "contactsView"; + private static final String KEY_SELECTED_GROUP = "selectedGroup"; + private static final String KEY_SELECTED_ACCOUNT = "selectedAccount"; + + private final class WelcomeContentObserver extends ContentObserver { + private WelcomeContentObserver(Handler handler) { + super(handler); + } + + @Override + public void onChange(boolean selfChange) { + mDrawerAdapter.notifyDataSetChanged(); + } + } + + public DrawerFragment() {} + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + if (activity instanceof DrawerFragmentListener) { + mListener = (DrawerFragmentListener) activity; + } else { + throw new IllegalArgumentException( + "Activity must implement " + DrawerFragmentListener.class.getName()); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + final View contentView = inflater.inflate(R.layout.drawer_fragment, null); + mDrawerRecyclerView = (RecyclerView) contentView.findViewById(R.id.list); + mDrawerRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); + mDrawerAdapter = new DrawerAdapter(getActivity()); + mDrawerAdapter.setSelectedContactsView(mCurrentContactsView); + mDrawerAdapter.setItemOnClickListener(mOnDrawerItemClickListener); + loadGroupsAndFilters(); + mDrawerRecyclerView.setAdapter(mDrawerAdapter); + + if (savedInstanceState != null) { + final ContactsView contactsView = + ContactsView.values()[savedInstanceState.getInt(KEY_CONTACTS_VIEW)]; + setNavigationItemChecked(contactsView); + final long groupId = savedInstanceState.getLong(KEY_SELECTED_GROUP); + mDrawerAdapter.setSelectedGroupId(groupId); + final ContactListFilter filter = savedInstanceState.getParcelable(KEY_SELECTED_ACCOUNT); + mDrawerAdapter.setSelectedAccount(filter); + } else { + setNavigationItemChecked(ContactsView.ALL_CONTACTS); + } + + return contentView; + } + + @Override + public void onResume() { + super.onResume(); + // todo double check on the new Handler() thing + final Uri uri = ObjectFactory.getWelcomeUri(); + if (uri != null) { + mObserver = new WelcomeContentObserver(new Handler()); + getActivity().getContentResolver().registerContentObserver(uri, false, mObserver); + } + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt(KEY_CONTACTS_VIEW, mCurrentContactsView.ordinal()); + outState.putLong(KEY_SELECTED_GROUP, mDrawerAdapter.getSelectedGroupId()); + outState.putParcelable(KEY_SELECTED_ACCOUNT, mDrawerAdapter.getSelectedAccount()); + } + + @Override + public void onPause() { + super.onPause(); + if (mObserver != null) { + getActivity().getContentResolver().unregisterContentObserver(mObserver); + } + } + + // TODO create loaders in this fragment instead of having separate fragments that just kick off + // some data loading. + private void loadGroupsAndFilters() { + final FragmentManager fragmentManager = getFragmentManager(); + final FragmentTransaction transaction = fragmentManager.beginTransaction(); + mGroupsFragment = (GroupsFragment) fragmentManager.findFragmentByTag(TAG_GROUPS); + if (mGroupsFragment == null) { + mGroupsFragment = new GroupsFragment(); + transaction.add(mGroupsFragment, TAG_GROUPS); + } + mGroupsFragment.setListener(this); + + mAccountFiltersFragment = (AccountFiltersFragment) + fragmentManager.findFragmentByTag(TAG_FILTERS); + if (mAccountFiltersFragment == null) { + mAccountFiltersFragment = new AccountFiltersFragment(); + transaction.add(mAccountFiltersFragment, TAG_FILTERS); + } + mAccountFiltersFragment.setListener(this); + transaction.commitAllowingStateLoss(); + fragmentManager.executePendingTransactions(); + } + + @Override + public void onDetach() { + super.onDetach(); + mListener = null; + } + + private final View.OnClickListener mOnDrawerItemClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mListener == null) { + return; + } + mListener.onDrawerItemClicked(); + final int viewId = v.getId(); + if (viewId == R.id.nav_all_contacts) { + mListener.onContactsViewSelected(ContactsView.ALL_CONTACTS); + setNavigationItemChecked(ContactsView.ALL_CONTACTS); + } else if (viewId == R.id.nav_assistant) { + mListener.onContactsViewSelected(ContactsView.ASSISTANT); + setNavigationItemChecked(ContactsView.ASSISTANT); + } else if (viewId == R.id.nav_group) { + final GroupListItem groupListItem = (GroupListItem) v.getTag(); + mListener.onGroupViewSelected(groupListItem); + mDrawerAdapter.setSelectedGroupId(groupListItem.getGroupId()); + setNavigationItemChecked(ContactsView.GROUP_VIEW); + } else if (viewId == R.id.nav_filter) { + final ContactListFilter filter = (ContactListFilter) v.getTag(); + mListener.onAccountViewSelected(filter); + mDrawerAdapter.setSelectedAccount(filter); + setNavigationItemChecked(ContactsView.ACCOUNT_VIEW); + } else if (viewId == R.id.nav_create_label) { + mListener.onCreateLabelButtonClicked(); + } else if (viewId == R.id.nav_settings) { + mListener.onOpenSettings(); + } else if (viewId == R.id.nav_help) { + mListener.onLaunchHelpFeedback(); + } else { + throw new IllegalStateException("Unknown view"); + } + } + }; + + public void setNavigationItemChecked(ContactsView contactsView) { + mCurrentContactsView = contactsView; + if (mDrawerAdapter != null) { + mDrawerAdapter.setSelectedContactsView(contactsView); + } + } + + @Override + public void onGroupsLoaded(List<GroupListItem> groupListItems, boolean areGroupWritable) { + final Iterator<GroupListItem> iterator = groupListItems.iterator(); + while (iterator.hasNext()) { + final GroupListItem groupListItem = iterator.next(); + if (GroupUtil.isEmptyFFCGroup(groupListItem)) { + iterator.remove(); + } + } + mDrawerAdapter.setGroups(groupListItems, areGroupWritable); + } + + public void updateGroupMenu(long groupId) { + mDrawerAdapter.setSelectedGroupId(groupId); + setNavigationItemChecked(ContactsView.GROUP_VIEW); + } + + @Override + public void onFiltersLoaded(List<ContactListFilter> accountFilterItems) { + if (accountFilterItems == null || accountFilterItems.size() < 2) { + mDrawerAdapter.setAccounts(new ArrayList<ContactListFilter>()); + } else { + mDrawerAdapter.setAccounts(accountFilterItems); + } + } + + public interface DrawerFragmentListener { + void onDrawerItemClicked(); + void onContactsViewSelected(ContactsView mode); + void onGroupViewSelected(GroupListItem groupListItem); + void onAccountViewSelected(ContactListFilter filter); + void onCreateLabelButtonClicked(); + void onOpenSettings(); + void onLaunchHelpFeedback(); + } +} diff --git a/src/com/android/contacts/group/GroupMembersFragment.java b/src/com/android/contacts/group/GroupMembersFragment.java index 31938d719..0d2410d0f 100644 --- a/src/com/android/contacts/group/GroupMembersFragment.java +++ b/src/com/android/contacts/group/GroupMembersFragment.java @@ -730,8 +730,8 @@ public class GroupMembersFragment extends MultiSelectContactsListFragment<GroupM maybeAttachCheckBoxListener(); mActivity.setTitle(mGroupMetaData.groupName); - mActivity.updateGroupMenu(mGroupMetaData); mActivity.invalidateOptionsMenu(); + mActivity.updateDrawerGroupMenu(mGroupMetaData.groupId); // Start loading the group members super.startLoading(); |