summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/drawable/action_bar_tab.xml38
-rw-r--r--res/drawable/tab_selected_focused.xml31
-rw-r--r--res/drawable/tab_unselected_focused.xml28
-rw-r--r--res/drawable/view_pager_tab_background.xml22
-rw-r--r--res/layout-land/people_activity_toolbar.xml35
-rw-r--r--res/layout/people_activity.xml5
-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.xml46
-rw-r--r--res/values-w470dp/dimens.xml28
-rw-r--r--res/values-w590dp/dimens.xml28
-rw-r--r--res/values/colors.xml4
-rw-r--r--res/values/dimens.xml9
-rw-r--r--res/values/styles.xml18
-rw-r--r--src/com/android/contacts/activities/ActionBarAdapter.java178
-rw-r--r--src/com/android/contacts/activities/PeopleActivity.java45
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) {