diff options
-rw-r--r-- | res/drawable/action_bar_tab.xml | 38 | ||||
-rw-r--r-- | res/drawable/tab_selected_focused.xml | 31 | ||||
-rw-r--r-- | res/drawable/tab_unselected_focused.xml | 28 | ||||
-rw-r--r-- | res/drawable/view_pager_tab_background.xml | 22 | ||||
-rw-r--r-- | res/layout-land/people_activity_toolbar.xml | 35 | ||||
-rw-r--r-- | res/layout/people_activity.xml | 5 | ||||
-rw-r--r-- | res/layout/people_activity_tabs_lands.xml (renamed from res/drawable/tab_selected.xml) | 22 | ||||
-rw-r--r-- | res/layout/people_activity_toolbar.xml | 46 | ||||
-rw-r--r-- | res/values-w470dp/dimens.xml | 28 | ||||
-rw-r--r-- | res/values-w590dp/dimens.xml | 28 | ||||
-rw-r--r-- | res/values/colors.xml | 4 | ||||
-rw-r--r-- | res/values/dimens.xml | 9 | ||||
-rw-r--r-- | res/values/styles.xml | 18 | ||||
-rw-r--r-- | src/com/android/contacts/activities/ActionBarAdapter.java | 178 | ||||
-rw-r--r-- | src/com/android/contacts/activities/PeopleActivity.java | 45 |
15 files changed, 331 insertions, 206 deletions
diff --git a/res/drawable/action_bar_tab.xml b/res/drawable/action_bar_tab.xml deleted file mode 100644 index 3982a3bb3..000000000 --- a/res/drawable/action_bar_tab.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2013 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/tab_pressed_color"> - <item> - <selector> - <item android:drawable="@drawable/tab_selected" - android:state_focused="false" - android:state_pressed="false" - android:state_selected="true" /> - <item android:drawable="@drawable/tab_selected_focused" - android:state_focused="true" - android:state_pressed="false" - android:state_selected="true" /> - <item android:drawable="@drawable/tab_unselected_focused" - android:state_focused="true" - android:state_pressed="false" - android:state_selected="false" /> - <item android:drawable="@drawable/tab_selected" - android:state_selected="true" /> - <item android:drawable="@color/tab_default_color" /> - </selector> - </item> -</ripple>
\ No newline at end of file diff --git a/res/drawable/tab_selected_focused.xml b/res/drawable/tab_selected_focused.xml deleted file mode 100644 index ba5162ae1..000000000 --- a/res/drawable/tab_selected_focused.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2013 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. ---> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > - <!-- Tab selected underline --> - <item android:drawable="@color/tab_selected_color" /> - <!-- Tab background --> - <item android:drawable="@color/tab_default_color" - android:bottom="@dimen/tab_selected_underline_height" /> - <!-- Focus rectangle --> - <item> - <shape android:shape="rectangle" > - <stroke - android:width="@dimen/tab_focused_stroke_width" - android:color="@color/focus_color" /> - </shape> - </item> -</layer-list>
\ No newline at end of file diff --git a/res/drawable/tab_unselected_focused.xml b/res/drawable/tab_unselected_focused.xml deleted file mode 100644 index 1e4c6c34d..000000000 --- a/res/drawable/tab_unselected_focused.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2013 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. ---> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <!-- Tab background --> - <item android:drawable="@color/tab_default_color" /> - <!-- Focus rectangle --> - <item> - <shape android:shape="rectangle" > - <stroke - android:width="@dimen/tab_focused_stroke_width" - android:color="@color/focus_color" /> - </shape> - </item> -</layer-list>
\ No newline at end of file diff --git a/res/drawable/view_pager_tab_background.xml b/res/drawable/view_pager_tab_background.xml new file mode 100644 index 000000000..1ba6c57e0 --- /dev/null +++ b/res/drawable/view_pager_tab_background.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2014 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/tab_ripple_color"> + <item android:id="@android:id/mask"> + <color android:color="@android:color/white" /> + </item> +</ripple>
\ No newline at end of file diff --git a/res/layout-land/people_activity_toolbar.xml b/res/layout-land/people_activity_toolbar.xml new file mode 100644 index 000000000..1f868794f --- /dev/null +++ b/res/layout-land/people_activity_toolbar.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + +<!-- Need to set a non null background on Toolbar in order for MenuItem ripples to be drawn on + this view, instead of another. This will *not* cause an additional draw since the + background is transparent.--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/toolbar_parent" + android:orientation="vertical" + android:layout_width="match_parent" + android:background="#00000000" + android:elevation="@dimen/tab_elevation" + android:layout_height="wrap_content" > + + <Toolbar + android:layout_width="match_parent" + android:layout_height="?android:attr/actionBarSize" + android:background="@color/actionbar_background_color" + android:id="@+id/toolbar" + style="@style/ContactsToolbarStyle" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/people_activity.xml b/res/layout/people_activity.xml index 6b6594577..2624818cf 100644 --- a/res/layout/people_activity.xml +++ b/res/layout/people_activity.xml @@ -19,6 +19,10 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + <include + layout="@layout/people_activity_toolbar" + android:id="@+id/toolbar_parent" /> + <!-- ViewPager for swiping between tabs. We put StrequentContactListFragment, DefaultContactBrowseListFragment and GroupBrowseListFragment at runtime. @@ -30,6 +34,7 @@ android:id="@+id/tab_pager" android:layout_height="match_parent" android:layout_width="match_parent" + android:layout_below="@id/toolbar_parent" /> <FrameLayout diff --git a/res/drawable/tab_selected.xml b/res/layout/people_activity_tabs_lands.xml index 9eec3c456..525ac3cec 100644 --- a/res/drawable/tab_selected.xml +++ b/res/layout/people_activity_tabs_lands.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2013 The Android Open Source Project +<!-- Copyright (C) 2014 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. @@ -14,10 +13,15 @@ See the License for the specific language governing permissions and limitations under the License. --> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > - <!-- Tab selected underline --> - <item android:drawable="@color/tab_selected_color" /> - <!-- Tab background --> - <item android:drawable="@color/tab_default_color" - android:bottom="@dimen/tab_selected_underline_height" /> -</layer-list>
\ No newline at end of file + +<com.android.contacts.common.list.ViewPagerTabs + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/lists_pager_header" + android:layout_width="@dimen/people_activity_landscape_tabs_width" + android:layout_height="match_parent" + android:textAllCaps="true" + android:orientation="horizontal" + android:layout_gravity="top" + android:layout_weight="0" + android:textSize="@dimen/people_activity_landscape_tabs_text_size" + style="@style/ContactsActionBarTabTextStyle" /> diff --git a/res/layout/people_activity_toolbar.xml b/res/layout/people_activity_toolbar.xml new file mode 100644 index 000000000..fe5be0499 --- /dev/null +++ b/res/layout/people_activity_toolbar.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + +<!-- Need to set a non null background on Toolbar in order for MenuItem ripples to be drawn on + this view, instead of another. This will *not* cause an additional draw since the + background is transparent.--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/toolbar_parent" + android:orientation="vertical" + android:layout_width="match_parent" + android:background="#00000000" + android:elevation="@dimen/tab_elevation" + android:layout_height="wrap_content" > + + <Toolbar + android:layout_width="match_parent" + android:layout_height="?android:attr/actionBarSize" + android:background="@color/actionbar_background_color" + android:id="@+id/toolbar" + style="@style/ContactsToolbarStyle" /> + + <com.android.contacts.common.list.ViewPagerTabs + android:id="@+id/lists_pager_header" + android:layout_width="match_parent" + android:layout_height="?android:attr/actionBarSize" + android:textAllCaps="true" + android:orientation="horizontal" + android:layout_gravity="top" + android:layout_weight="0" + android:layout_below="@id/toolbar" + style="@style/ContactsActionBarTabTextStyle" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/values-w470dp/dimens.xml b/res/values-w470dp/dimens.xml new file mode 100644 index 000000000..2c04e5dfa --- /dev/null +++ b/res/values-w470dp/dimens.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> +<resources> + + <!-- The width the that the tabs occupy in the ActionBar when in landscape mode. + 470dp is the height of a "normal" screen. We should leave 240dp for + the title and menu items --> + <dimen name="people_activity_landscape_tabs_width">230dip</dimen> + <!-- The size of the text displayed in the ActionBar tabs in landscape mode. + Text in the tabs should must be width dependent, otherwise it won't fit in the tabs. + In portrait mode, the tabs look okay when overflowing their allocated space. + We have to be more careful in landscape. --> + <dimen name="people_activity_landscape_tabs_text_size">9dp</dimen> + +</resources>
\ No newline at end of file diff --git a/res/values-w590dp/dimens.xml b/res/values-w590dp/dimens.xml new file mode 100644 index 000000000..2fff6cab2 --- /dev/null +++ b/res/values-w590dp/dimens.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> +<resources> + + <!-- The width the that the tabs occupy in the ActionBar when in landscape mode. + 590dp is almost the height of a "large" screen. We should leave 240dp for + the title and menu items --> + <dimen name="people_activity_landscape_tabs_width">350dip</dimen> + <!-- The size of the text displayed in the ActionBar tabs in landscape mode. + Text in the tabs should must be width dependent, otherwise it won't fit in the tabs. + In portrait mode, the tabs look okay when overflowing their allocated space. + We have to be more careful in landscape. --> + <dimen name="people_activity_landscape_tabs_text_size">14dp</dimen> + +</resources>
\ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml index 562241e46..beedf6ac4 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -61,8 +61,4 @@ <!-- Background color of pinned header items. --> <color name="list_item_pinned_header_color">#f5f5f5</color> - - <color name="tab_default_color">@color/actionbar_background_color</color> - <color name="tab_pressed_color">@color/tab_selected_color</color> - <color name="tab_selected_color">#ffeeff41</color> </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 40adc9501..d86d9d727 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -188,6 +188,15 @@ <dimen name="expanding_entry_card_item_alternate_icon_margin_bottom">10dp</dimen> <dimen name="people_activity_card_elevation">2dp</dimen> + <!-- The width the that the tabs occupy in the ActionBar when in landscape mode. + 426dp is the height of a "small" screen. We should leave 240dp for + the title and menu items --> + <dimen name="people_activity_landscape_tabs_width">186dip</dimen> + <!-- The size of the text displayed in the ActionBar tabs in landscape mode. + Text in the tabs should must be width dependent, otherwise it won't fit in the tabs. + In portrait mode, the tabs look okay when overflowing their allocated space. + We have to be more careful in landscape. --> + <dimen name="people_activity_landscape_tabs_text_size">8dp</dimen> <dimen name="expanding_entry_card_item_icon_height">24dp</dimen> <dimen name="expanding_entry_card_item_icon_width">24dp</dimen> diff --git a/res/values/styles.xml b/res/values/styles.xml index a1a01d169..1eae4d0f8 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -50,8 +50,6 @@ <style name="PeopleTheme" parent="@android:style/Theme.Material.Light"> <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item> - <!-- Style for the tabs --> - <item name="android:actionBarTabStyle">@style/ContactsActionBarTabStyle</item> <!-- Style for the tab bar (for the divider between tabs) --> <item name="android:actionBarTabBarStyle">@style/ContactsActionBarTabBarStyle</item> <!-- Style for the tab bar text (for text on tabs) --> @@ -111,17 +109,17 @@ <item name="android:icon">@android:color/transparent</item> </style> + <!-- When this style was added, android:toolbarStyle was private. Therefore, this style + must be directly applied to every toolbar --> + <style name="ContactsToolbarStyle" parent="@android:style/Widget.Toolbar"> + <item name="android:titleTextAppearance">@style/ContactsActionBarTitleText</item> + </style> + <style name="ContactsPickerActionBarStyle" parent="@style/ContactsActionBarStyle"> <!-- when first loading, don't show title or up button --> <item name="android:displayOptions"></item> </style> - <!-- Styling for tabs. --> - <style name="ContactsActionBarTabStyle" parent="@android:style/Widget.Material.Light.ActionBar.TabView"> - <item name="android:background">@drawable/action_bar_tab</item> - <item name="android:showDividers">none</item> - </style> - <!-- Text in the action bar at the top of the screen --> <style name="ContactsActionBarTitleText" parent="@android:style/TextAppearance.Material.Widget.ActionBar.Title"> @@ -160,10 +158,6 @@ <item name="android:dropDownListViewStyle">@style/ListViewDropdownStyle</item> </style> - <style name="ContactsActionBarTabView" parent="@android:style/Widget.Holo.ActionBar.TabView"> - <item name="android:background">@drawable/action_bar_tab</item> - </style> - <style name="ListViewDropdownStyle" parent="@android:style/Widget.ListView.DropDown"> <item name="android:listSelector">?android:attr/listChoiceBackgroundIndicator</item> </style> diff --git a/src/com/android/contacts/activities/ActionBarAdapter.java b/src/com/android/contacts/activities/ActionBarAdapter.java index ea05b73e0..e27419a7e 100644 --- a/src/com/android/contacts/activities/ActionBarAdapter.java +++ b/src/com/android/contacts/activities/ActionBarAdapter.java @@ -16,22 +16,25 @@ package com.android.contacts.activities; +import android.animation.ValueAnimator; import android.app.ActionBar; -import android.app.ActionBar.Tab; -import android.app.FragmentTransaction; import android.content.Context; import android.content.SharedPreferences; +import android.content.res.TypedArray; import android.os.Bundle; import android.preference.PreferenceManager; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.SearchView; import android.widget.SearchView.OnCloseListener; import android.view.View.OnClickListener; import android.widget.EditText; +import android.widget.Toolbar; import com.android.contacts.R; import com.android.contacts.activities.ActionBarAdapter.Listener.Action; @@ -70,16 +73,22 @@ public class ActionBarAdapter implements OnCloseListener { private String mQueryString; private EditText mSearchView; + /** The view that represents tabs when we are in portrait mode **/ + private View mPortraitTabs; + /** The view that represents tabs when we are in landscape mode **/ + private View mLandscapeTabs; private View mSearchContainer; + private int mMaxPortraitTabHeight; + private int mMaxToolbarContentInsetStart; + private final Context mContext; private final SharedPreferences mPrefs; private Listener mListener; private final ActionBar mActionBar; - private final int mActionBarNavigationMode; - private final MyTabListener mTabListener; + private final Toolbar mToolbar; private boolean mShowHomeIcon; @@ -93,29 +102,38 @@ public class ActionBarAdapter implements OnCloseListener { private int mCurrentTab = TabState.DEFAULT; - public ActionBarAdapter(Context context, Listener listener, ActionBar actionBar) { + public ActionBarAdapter(Context context, Listener listener, ActionBar actionBar, + View portraitTabs, View landscapeTabs, Toolbar toolbar) { mContext = context; mListener = listener; mActionBar = actionBar; mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); - + mPortraitTabs = portraitTabs; + mLandscapeTabs = landscapeTabs; + mToolbar = toolbar; + mMaxToolbarContentInsetStart = mToolbar.getContentInsetStart(); mShowHomeIcon = mContext.getResources().getBoolean(R.bool.show_home_icon); - mActionBarNavigationMode = ActionBar.NAVIGATION_MODE_TABS; - mTabListener = new MyTabListener(); - setupSearchView(); - setupTabs(); + setupTabs(context); } - private void setupTabs() { - addTab(TabState.FAVORITES, R.string.favorites_tab_label); - addTab(TabState.ALL, R.string.all_contacts_tab_label); + private void setupTabs(Context context) { + final TypedArray attributeArray = context.obtainStyledAttributes( + new int[]{android.R.attr.actionBarSize}); + mMaxPortraitTabHeight = attributeArray.getDimensionPixelSize(0, 0); + // Hide tabs initially + setPortraitTabHeight(0); } private void setupSearchView() { - mActionBar.setCustomView(R.layout.search_bar_expanded); - mSearchContainer = mActionBar.getCustomView(); + final LayoutInflater inflater = (LayoutInflater) mToolbar.getContext().getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + mSearchContainer = inflater.inflate(R.layout.search_bar_expanded, mToolbar, + /* attachToRoot = */ false); + mSearchContainer.setVisibility(View.VISIBLE); + mToolbar.addView(mSearchContainer); + mSearchContainer.setBackgroundColor(mContext.getResources().getColor( R.color.searchbox_background_color)); mSearchView = (EditText) mSearchContainer.findViewById(R.id.search_view); @@ -137,7 +155,6 @@ public class ActionBarAdapter implements OnCloseListener { } } }); - mActionBar.setCustomView(mSearchContainer); } public void initialize(Bundle savedState, ContactsRequest request) { @@ -170,34 +187,6 @@ public class ActionBarAdapter implements OnCloseListener { mListener = listener; } - private void addTab(int expectedTabIndex, int description) { - final Tab tab = mActionBar.newTab(); - tab.setTabListener(mTabListener); - tab.setText(description); - mActionBar.addTab(tab); - if (expectedTabIndex != tab.getPosition()) { - throw new IllegalStateException("Tabs must be created in the right order"); - } - } - - private class MyTabListener implements ActionBar.TabListener { - /** - * If true, it won't call {@link #setCurrentTab} in {@link #onTabSelected}. - * This flag is used when we want to programmatically update the current tab without - * {@link #onTabSelected} getting called. - */ - public boolean mIgnoreTabSelected; - - @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { } - @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { } - - @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { - if (!mIgnoreTabSelected) { - setCurrentTab(tab.getPosition()); - } - } - } - private class SearchTextWatcher implements TextWatcher { @Override @@ -223,14 +212,14 @@ public class ActionBarAdapter implements OnCloseListener { } /** - * Change the current tab, and notify the listener. + * Save the current tab selection, and notify the listener. */ public void setCurrentTab(int tab) { setCurrentTab(tab, true); } /** - * Change the current tab + * Save the current tab selection. */ public void setCurrentTab(int tab, boolean notifyListener) { if (tab == mCurrentTab) { @@ -238,11 +227,6 @@ public class ActionBarAdapter implements OnCloseListener { } mCurrentTab = tab; - final int actionBarSelectedNavIndex = mActionBar.getSelectedNavigationIndex(); - if (mCurrentTab != actionBarSelectedNavIndex) { - mActionBar.setSelectedNavigationItem(mCurrentTab); - } - if (notifyListener && mListener != null) mListener.onSelectedTabChanged(); saveLastTabPreference(mCurrentTab); } @@ -295,7 +279,7 @@ public class ActionBarAdapter implements OnCloseListener { return mSearchMode; // Only shown on the search mode. } - private void updateDisplayOptions() { + private void updateDisplayOptionsInner() { // All the flags we may change in this method. final int MASK = ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_CUSTOM; @@ -310,10 +294,14 @@ public class ActionBarAdapter implements OnCloseListener { } if (mSearchMode) { newFlags |= ActionBar.DISPLAY_SHOW_CUSTOM; + mToolbar.setContentInsetsRelative(0, mToolbar.getContentInsetEnd()); } else { newFlags |= ActionBar.DISPLAY_SHOW_TITLE; + mToolbar.setContentInsetsRelative(mMaxToolbarContentInsetStart, + mToolbar.getContentInsetEnd()); } + if (current != newFlags) { // Pass the mask here to preserve other flags that we're not interested here. mActionBar.setDisplayOptions(newFlags, MASK); @@ -322,21 +310,26 @@ public class ActionBarAdapter implements OnCloseListener { private void update(boolean skipAnimation) { final boolean isIconifiedChanging - = (mSearchContainer.getVisibility() == View.VISIBLE) != mSearchMode; + = (mSearchContainer.getParent() == null) == mSearchMode; + mToolbar.removeView(mLandscapeTabs); if (isIconifiedChanging && !skipAnimation) { if (mSearchMode) { - mSearchContainer.setVisibility(View.VISIBLE); + mToolbar.removeView(mLandscapeTabs); + addSearchContainer(); mSearchContainer.setAlpha(0); mSearchContainer.animate().alpha(1); - updateDisplayOptionsAndNavigationMode(isIconifiedChanging); + animateTabHeightChange(mMaxPortraitTabHeight, 0); + updateDisplayOptions(isIconifiedChanging); } else { mSearchContainer.setAlpha(1); + animateTabHeightChange(0, mMaxPortraitTabHeight); mSearchContainer.animate().alpha(0).withEndAction(new Runnable() { @Override public void run() { - updateDisplayOptions(); - mSearchContainer.setVisibility(View.GONE); - updateDisplayOptionsAndNavigationMode(isIconifiedChanging); + updateDisplayOptionsInner(); + updateDisplayOptions(isIconifiedChanging); + addLandscapeViewPagerTabs(); + mToolbar.removeView(mSearchContainer); } }); } @@ -344,15 +337,31 @@ public class ActionBarAdapter implements OnCloseListener { } if (isIconifiedChanging && skipAnimation) { if (mSearchMode) { - mSearchContainer.setVisibility(View.VISIBLE); + setPortraitTabHeight(0); + mToolbar.removeView(mLandscapeTabs); + addSearchContainer(); } else { - mSearchContainer.setVisibility(View.GONE); + setPortraitTabHeight(mMaxPortraitTabHeight); + mToolbar.removeView(mSearchContainer); + addLandscapeViewPagerTabs(); } } - updateDisplayOptionsAndNavigationMode(isIconifiedChanging); + updateDisplayOptions(isIconifiedChanging); } - private void updateDisplayOptionsAndNavigationMode(boolean isIconifiedChanging) { + private void addLandscapeViewPagerTabs() { + if (mLandscapeTabs != null) { + mToolbar.removeView(mLandscapeTabs); + mToolbar.addView(mLandscapeTabs); + } + } + + private void addSearchContainer() { + mToolbar.removeView(mSearchContainer); + mToolbar.addView(mSearchContainer); + } + + private void updateDisplayOptions(boolean isIconifiedChanging) { if (mSearchMode) { setFocusOnSearchView(); // Since we have the {@link SearchView} in a custom action bar, we must manually handle @@ -364,35 +373,16 @@ public class ActionBarAdapter implements OnCloseListener { mSearchView.setText(queryText); } } - if (mActionBar.getNavigationMode() != ActionBar.NAVIGATION_MODE_STANDARD) { - mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); - } if (mListener != null) { mListener.onAction(Action.START_SEARCH_MODE); } } else { - final int currentNavigationMode = mActionBar.getNavigationMode(); - if (mActionBarNavigationMode == ActionBar.NAVIGATION_MODE_TABS - && currentNavigationMode != ActionBar.NAVIGATION_MODE_TABS) { - // setNavigationMode will trigger onTabSelected() with the tab which was previously - // selected. - // The issue is that when we're first switching to the tab navigation mode after - // screen orientation changes, onTabSelected() will get called with the first tab - // (i.e. favorite), which would results in mCurrentTab getting set to FAVORITES and - // we'd lose restored tab. - // So let's just disable the callback here temporarily. We'll notify the listener - // after this anyway. - mTabListener.mIgnoreTabSelected = true; - mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); - mActionBar.setSelectedNavigationItem(mCurrentTab); - mTabListener.mIgnoreTabSelected = false; - } if (mListener != null) { mListener.onAction(Action.STOP_SEARCH_MODE); mListener.onSelectedTabChanged(); } } - updateDisplayOptions(); + updateDisplayOptionsInner(); } @Override @@ -444,4 +434,28 @@ public class ActionBarAdapter implements OnCloseListener { return TabState.DEFAULT; } } + + private void animateTabHeightChange(int start, int end) { + if (mPortraitTabs == null) { + return; + } + final ValueAnimator animator = ValueAnimator.ofInt(start, end); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + int value = (Integer) valueAnimator.getAnimatedValue(); + setPortraitTabHeight(value); + } + }); + animator.setDuration(100).start(); + } + + private void setPortraitTabHeight(int height) { + if (mPortraitTabs == null) { + return; + } + ViewGroup.LayoutParams layoutParams = mPortraitTabs.getLayoutParams(); + layoutParams.height = height; + mPortraitTabs.setLayoutParams(layoutParams); + } } diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java index 5759350e4..7c0b14b6f 100644 --- a/src/com/android/contacts/activities/PeopleActivity.java +++ b/src/com/android/contacts/activities/PeopleActivity.java @@ -19,7 +19,9 @@ package com.android.contacts.activities; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; +import android.content.Context; import android.content.Intent; +import android.content.res.TypedArray; import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; @@ -43,7 +45,9 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.Window; import android.widget.ImageButton; +import android.widget.Toolbar; import com.android.contacts.ContactsActivity; import com.android.contacts.R; @@ -67,6 +71,7 @@ import com.android.contacts.list.OnContactBrowserActionListener; import com.android.contacts.list.OnContactsUnavailableActionListener; import com.android.contacts.list.ProviderStatusWatcher; import com.android.contacts.list.ProviderStatusWatcher.ProviderStatusListener; +import com.android.contacts.common.list.ViewPagerTabs; import com.android.contacts.preference.ContactsPreferenceActivity; import com.android.contacts.common.util.AccountFilterUtil; import com.android.contacts.common.util.ViewUtil; @@ -123,7 +128,9 @@ public class PeopleActivity extends ContactsActivity implements /** ViewPager for swipe */ private ViewPager mTabPager; + private ViewPagerTabs mViewPagerTabs; private TabPagerAdapter mTabPagerAdapter; + private String[] mTabTitles; private final TabPagerListener mTabPagerListener = new TabPagerListener(); private boolean mEnableDebugMenuOptions; @@ -277,6 +284,10 @@ public class PeopleActivity extends ContactsActivity implements } private void createViewsAndFragments(Bundle savedState) { + // Disable the ActionBar so that we can use a Toolbar. This needs to be called before + // setContentView(). + getWindow().requestFeature(Window.FEATURE_NO_TITLE); + setContentView(R.layout.people_activity); final FragmentManager fragmentManager = getFragmentManager(); @@ -284,11 +295,29 @@ public class PeopleActivity extends ContactsActivity implements // Hide all tabs (the current tab will later be reshown once a tab is selected) final FragmentTransaction transaction = fragmentManager.beginTransaction(); + mTabTitles = new String[TabState.COUNT]; + mTabTitles[TabState.FAVORITES] = getString(R.string.favorites_tab_label); + mTabTitles[TabState.ALL] = getString(R.string.all_contacts_tab_label); mTabPager = getView(R.id.tab_pager); mTabPagerAdapter = new TabPagerAdapter(); mTabPager.setAdapter(mTabPagerAdapter); mTabPager.setOnPageChangeListener(mTabPagerListener); + // Configure toolbar and toolbar tabs. If in landscape mode, we configure tabs differntly. + final Toolbar toolbar = getView(R.id.toolbar); + setActionBar(toolbar); + final ViewPagerTabs portraitViewPagerTabs + = (ViewPagerTabs) findViewById(R.id.lists_pager_header); + ViewPagerTabs landscapeViewPagerTabs = null; + if (portraitViewPagerTabs == null) { + landscapeViewPagerTabs = (ViewPagerTabs) getLayoutInflater().inflate( + R.layout.people_activity_tabs_lands, toolbar, /* attachToRoot = */ false); + mViewPagerTabs = landscapeViewPagerTabs; + } else { + mViewPagerTabs = portraitViewPagerTabs; + } + mViewPagerTabs.setViewPager(mTabPager); + final String FAVORITE_TAG = "tab-pager-favorite"; final String ALL_TAG = "tab-pager-all"; @@ -326,8 +355,8 @@ public class PeopleActivity extends ContactsActivity implements // Setting Properties after fragment is created mFavoritesFragment.setDisplayType(DisplayType.STREQUENT); - // Configure action bar - mActionBarAdapter = new ActionBarAdapter(this, this, getActionBar()); + mActionBarAdapter = new ActionBarAdapter(this, this, getActionBar(), + portraitViewPagerTabs, landscapeViewPagerTabs, toolbar); mActionBarAdapter.initialize(savedState, mRequest); // Configure action button @@ -572,10 +601,16 @@ public class PeopleActivity extends ContactsActivity implements @Override public void onPageScrollStateChanged(int state) { + if (!mTabPagerAdapter.isSearchMode()) { + mViewPagerTabs.onPageScrollStateChanged(state); + } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + if (!mTabPagerAdapter.isSearchMode()) { + mViewPagerTabs.onPageScrolled(position, positionOffset, positionOffsetPixels); + } } @Override @@ -583,6 +618,7 @@ public class PeopleActivity extends ContactsActivity implements // Make sure not in the search mode, in which case position != TabState.ordinal(). if (!mTabPagerAdapter.isSearchMode()) { mActionBarAdapter.setCurrentTab(position, false); + mViewPagerTabs.onPageSelected(position); showEmptyStateForTab(position); invalidateOptionsMenu(); } @@ -726,6 +762,11 @@ public class PeopleActivity extends ContactsActivity implements @Override public void restoreState(Parcelable state, ClassLoader loader) { } + + @Override + public CharSequence getPageTitle(int position) { + return mTabTitles[position]; + } } private void setQueryTextToFragment(String query) { |