aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/HorizontalTabView.java244
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderSubsActivity.java4
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserActivity.java41
-rw-r--r--WordPress/src/main/java/org/wordpress/android/widgets/SlidingTabLayout.java325
-rw-r--r--WordPress/src/main/java/org/wordpress/android/widgets/SlidingTabStrip.java171
-rw-r--r--WordPress/src/main/res/color/tab_text_color.xml5
-rw-r--r--WordPress/src/main/res/layout/reader_activity_subs.xml3
-rw-r--r--WordPress/src/main/res/layout/tab_text.xml15
-rw-r--r--WordPress/src/main/res/layout/theme_browser_activity.xml18
-rw-r--r--WordPress/src/main/res/values/colors.xml9
-rw-r--r--WordPress/src/main/res/values/reader_styles.xml6
-rw-r--r--WordPress/src/main/res/values/styles.xml1
12 files changed, 548 insertions, 294 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/HorizontalTabView.java b/WordPress/src/main/java/org/wordpress/android/ui/HorizontalTabView.java
deleted file mode 100644
index 9791c28f3..000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/HorizontalTabView.java
+++ /dev/null
@@ -1,244 +0,0 @@
-package org.wordpress.android.ui;
-
-import java.util.ArrayList;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.graphics.Paint;
-import android.graphics.Typeface;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.HorizontalScrollView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.wordpress.android.R;
-import org.wordpress.android.util.BlogUtils;
-import org.wordpress.android.util.DisplayUtils;
-
-/**
- * A view that mimics the action bar tabs. It can be placed anywhere and appears
- * under the sliding menu, unlike the action bar tabs
- */
-
-public class HorizontalTabView extends HorizontalScrollView implements OnClickListener {
- private static final String TAG_PREFIX = "tab:";
- private ArrayList<Tab> mTabs;
- private ArrayList<TextView> mTextViews;
- private LinearLayout mTabContainer;
- private float mMaxTabWidth = 0f;
- private TabListener mTabListener;
- private boolean mEnableScroll = true;
- private LinearLayout mSelectedLayout;
-
- public HorizontalTabView(Context context) {
- super(context);
- init();
- }
- public HorizontalTabView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
- public HorizontalTabView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init();
- }
-
- private void init() {
- mTabs = new ArrayList<Tab>();
- mTextViews = new ArrayList<TextView>();
-
- setupBackground();
- setupTabContainer();
- }
-
- private void setupBackground() {
- setBackgroundColor(getResources().getColor(R.color.tab_background));
- }
-
- private void setupTabContainer() {
- mTabContainer = new LinearLayout(getContext());
- HorizontalScrollView.LayoutParams linearLayoutParams =
- new HorizontalScrollView.LayoutParams(HorizontalScrollView.LayoutParams.WRAP_CONTENT, HorizontalScrollView.LayoutParams.WRAP_CONTENT);
- mTabContainer.setLayoutParams(linearLayoutParams);
- mTabContainer.setOrientation(LinearLayout.HORIZONTAL);
-
- addView(mTabContainer);
-
- }
- public Tab newTab() {
- return new Tab();
- }
-
- public void addTab(Tab tab) {
- tab.setPosition(mTabs.size());
- mTabs.add(tab);
-
- Context context = getContext();
-
- int divWidth = DisplayUtils.dpToPx(context, 1);
- int divTopMargin = DisplayUtils.dpToPx(context, 12);
- int divHeight = DisplayUtils.dpToPx(context, 24);
-
- int tabPad = DisplayUtils.dpToPx(context, 16);
-
- int fontSizeSp = 12;
-
- // add dividers in the middle - not using divider property as it is API 11
- if (mTextViews.size() > 0) {
- View divider = new View(getContext());
- LinearLayout.LayoutParams separatorParams = new LinearLayout.LayoutParams(divWidth, divHeight);
- separatorParams.topMargin = divTopMargin;
- divider.setLayoutParams(separatorParams);
- divider.setBackgroundColor(getResources().getColor(R.color.tab_divider));
- mTabContainer.addView(divider);
- }
-
- TextView textView = new TextView(getContext());
- LinearLayout.LayoutParams textViewParams =
- new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
- textView.setLayoutParams(textViewParams);
- textView.setGravity(Gravity.CENTER);
- textView.setText(tab.getText());
- textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSizeSp);
- textView.setTextColor(getResources().getColor(R.color.tab_text));
- textView.setTypeface(null, Typeface.BOLD);
-
- mTextViews.add(textView);
-
- LinearLayout linearLayout = new LinearLayout(getContext());
- LinearLayout.LayoutParams linearLayoutParams =
- new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1);
- linearLayout.setLayoutParams(linearLayoutParams);
- linearLayout.addView(textView);
- linearLayout.setTag(TAG_PREFIX + (mTabs.size()-1));
- linearLayout.setOnClickListener(this);
- linearLayout.setBackgroundResource(R.drawable.tab_indicator_ab_wordpress);
- linearLayout.setPadding(tabPad, tabPad, tabPad, tabPad);
-
- mTabContainer.addView(linearLayout);
-
- recomputeTabWidths();
- }
-
- /** Make the tabs have the same widths, where this width is based on the longest tab title **/
- private void recomputeTabWidths() {
- // Determine the max width
- for(TextView textView : mTextViews) {
- Paint paint = textView.getPaint();
- float width = paint.measureText(textView.getText().toString());
- if (mMaxTabWidth < width)
- mMaxTabWidth = width;
- }
-
- // Set the tabs to use the max width
- for(TextView textView : mTextViews) {
- LinearLayout.LayoutParams textViewParams =
- new LinearLayout.LayoutParams((int) mMaxTabWidth, LinearLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
- textView.setLayoutParams(textViewParams);
- }
-
- }
-
- public class Tab {
- private String mText;
- private int mPosition;
-
- @SuppressLint("DefaultLocale")
- public CharSequence getText() {
- return mText.toUpperCase();
- }
-
- public Tab setText(CharSequence pageTitle) {
- mText = pageTitle.toString();
- return this;
- }
-
- public int getPosition() {
- return mPosition;
- }
-
- public void setPosition(int position) {
- this.mPosition = position;
- }
- }
-
- public interface TabListener {
- public void onTabSelected(Tab tab);
- }
-
- public TabListener getTabListener() {
- return mTabListener;
- }
-
- public void setTabListener(TabListener tabListener) {
- this.mTabListener = tabListener;
- }
-
- @Override
- public void onClick(View v) {
- if (v instanceof LinearLayout) {
- LinearLayout layout = (LinearLayout) v;
-
- String tag = (String) layout.getTag();
- int position = Integer.valueOf(tag.substring(TAG_PREFIX.length()));
-
- // It is necessary to disable scrolling upon click before informing the listener
- // because I've found that if setSelectedTab() was called in the listener implementation,
- // and that setSelectedTab() is called again after onTabSelected(), it does not smooth scroll.
-
- // The call to setSelectedTab() in this method is necessary because if there was no listener or if
- // it did not call setSelectedTab(), then it would appear as if nothing happened.
-
- mEnableScroll = false;
-
- if (mTabListener != null)
- mTabListener.onTabSelected(mTabs.get(position));
-
- mEnableScroll = true;
-
- setSelectedTab(position);
- }
- }
-
- public void setSelectedTab(int position) {
- if (position >= mTextViews.size())
- return;
-
- if (mEnableScroll) {
- scrollToTab(position);
- setSelectedLayout(getTabParent(position));
- }
- }
-
- public void setTabText(int position, String text) {
- mTabs.get(position).mText = text;
- mTextViews.get(position).setText(text);
- }
-
- private void scrollToTab(int position) {
- int tabWidth = getTabParent(position).getWidth();
- int parentWidth = ((View) this.getParent()).getWidth();
-
- int offset = parentWidth / 2 - tabWidth / 2;
-
- smoothScrollTo(tabWidth * position - offset, 0);
- }
-
- private LinearLayout getTabParent(int position) {
- View tab = mTextViews.get(position);
- return (LinearLayout) tab.getParent();
- }
-
- private void setSelectedLayout(LinearLayout layout) {
- if (mSelectedLayout != null) {
- mSelectedLayout.setSelected(false);
- }
-
- mSelectedLayout = (LinearLayout)layout;
- mSelectedLayout.setSelected(true);
- }
-} \ No newline at end of file
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderSubsActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderSubsActivity.java
index eeaec61b8..61c840d26 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderSubsActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderSubsActivity.java
@@ -103,8 +103,8 @@ public class ReaderSubsActivity extends ActionBarActivity
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
PagerTabStrip tabStrip = (PagerTabStrip) findViewById(R.id.pager_tabs);
- tabStrip.setTabIndicatorColorResource(R.color.blue_light);
- tabStrip.setBackgroundColor(getResources().getColor(R.color.color_primary));
+ tabStrip.setTabIndicatorColorResource(R.color.tab_indicator);
+ tabStrip.setTextColor(getResources().getColor(R.color.tab_text_selected));
mEditAdd = (EditText) findViewById(R.id.edit_add);
mEditAdd.setOnEditorActionListener(new TextView.OnEditorActionListener() {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserActivity.java
index c33f99ecc..5e79945af 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserActivity.java
@@ -25,9 +25,8 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.wordpress.android.R;
import org.wordpress.android.WordPress;
+import org.wordpress.android.analytics.AnalyticsTracker;
import org.wordpress.android.models.Theme;
-import org.wordpress.android.ui.HorizontalTabView;
-import org.wordpress.android.ui.HorizontalTabView.TabListener;
import org.wordpress.android.ui.WPDrawerActivity;
import org.wordpress.android.ui.posts.PostsActivity;
import org.wordpress.android.ui.themes.ThemeDetailsFragment.ThemeDetailsFragmentCallback;
@@ -38,8 +37,8 @@ import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
import org.wordpress.android.util.DisplayUtils;
import org.wordpress.android.util.NetworkUtils;
+import org.wordpress.android.widgets.SlidingTabLayout;
import org.wordpress.android.widgets.WPAlertDialogFragment;
-import org.wordpress.android.analytics.AnalyticsTracker;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -48,11 +47,11 @@ import java.util.ArrayList;
* The theme browser. Accessible via side menu drawer.
*/
public class ThemeBrowserActivity extends WPDrawerActivity implements
- ThemeTabFragmentCallback, ThemeDetailsFragmentCallback, ThemePreviewFragmentCallback,
- TabListener {
- private HorizontalTabView mTabView;
+ ThemeTabFragmentCallback, ThemeDetailsFragmentCallback, ThemePreviewFragmentCallback {
+
private ThemePagerAdapter mThemePagerAdapter;
private ViewPager mViewPager;
+ private SlidingTabLayout mTabLayout;
private ThemeSearchFragment mSearchFragment;
private ThemePreviewFragment mPreviewFragment;
private ThemeDetailsFragment mDetailsFragment;
@@ -91,23 +90,12 @@ public class ThemeBrowserActivity extends WPDrawerActivity implements
mViewPager = (ViewPager) findViewById(R.id.theme_browser_pager);
mViewPager.setAdapter(mThemePagerAdapter);
- mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
- @Override
- public void onPageSelected(int position) {
- mTabView.setSelectedTab(position);
- }
- });
-
- mTabView = (HorizontalTabView) findViewById(R.id.horizontalTabView1);
- mTabView.setTabListener(this);
- int count = ThemeSortType.values().length;
- for (int i = 0; i < count; i++) {
- String title = ThemeSortType.values()[i].getTitle();
-
- mTabView.addTab(mTabView.newTab().setText(title));
- }
- mTabView.setSelectedTab(0);
+ mTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
+ mTabLayout.setCustomTabView(R.layout.tab_text, R.id.text_tab);
+ mTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.tab_indicator));
+ mTabLayout.setDistributeEvenly(true);
+ mTabLayout.setViewPager(mViewPager);
FragmentManager fm = getFragmentManager();
fm.addOnBackStackChangedListener(mOnBackStackChangedListener);
@@ -138,10 +126,10 @@ public class ThemeBrowserActivity extends WPDrawerActivity implements
int backstackCount = getFragmentManager().getBackStackEntryCount();
if (backstackCount == 0) {
mViewPager.setVisibility(View.VISIBLE);
- mTabView.setVisibility(View.VISIBLE);
+ mTabLayout.setVisibility(View.VISIBLE);
} else {
mViewPager.setVisibility(View.GONE);
- mTabView.setVisibility(View.GONE);
+ mTabLayout.setVisibility(View.GONE);
}
if (getDrawerToggle() != null) {
@@ -164,11 +152,6 @@ public class ThemeBrowserActivity extends WPDrawerActivity implements
}
}
- @Override
- public void onTabSelected(HorizontalTabView.Tab tab) {
- mViewPager.setCurrentItem(tab.getPosition());
- }
-
public class ThemePagerAdapter extends FragmentStatePagerAdapter {
ThemeTabFragment[] mTabFragment = new ThemeTabFragment[ThemeSortType.values().length];
diff --git a/WordPress/src/main/java/org/wordpress/android/widgets/SlidingTabLayout.java b/WordPress/src/main/java/org/wordpress/android/widgets/SlidingTabLayout.java
new file mode 100644
index 000000000..fa675dcd9
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/widgets/SlidingTabLayout.java
@@ -0,0 +1,325 @@
+/*
+<<<<<<< Updated upstream
+ * Copyright (C) 2013 The Android Open Source Project
+=======
+ * Copyright 2014 Google Inc. All rights reserved.
+>>>>>>> Stashed changes
+ *
+ * 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 org.wordpress.android.widgets;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.HorizontalScrollView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * To be used with ViewPager to provide a tab indicator component which give constant feedback as to
+ * the user's scroll progress.
+ * <p>
+ * To use the component, simply add it to your view hierarchy. Then in your
+ * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
+ * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
+ * <p>
+ * The colors can be customized in two ways. The first and simplest is to provide an array of colors
+ * via {@link #setSelectedIndicatorColors(int...)}. The
+ * alternative is via the {@link TabColorizer} interface which provides you complete control over
+ * which color is used for any individual position.
+ * <p>
+ * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
+ * providing the layout ID of your custom layout.
+ */
+public class SlidingTabLayout extends HorizontalScrollView {
+ /**
+ * Allows complete control over the colors drawn in the tab layout. Set with
+ * {@link #setCustomTabColorizer(TabColorizer)}.
+ */
+ public interface TabColorizer {
+
+ /**
+ * @return return the color of the indicator used when {@code position} is selected.
+ */
+ int getIndicatorColor(int position);
+
+ }
+
+ private static final int TITLE_OFFSET_DIPS = 24;
+ private static final int TAB_VIEW_PADDING_DIPS = 16;
+ private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
+
+ private int mTitleOffset;
+
+ private int mTabViewLayoutId;
+ private int mTabViewTextViewId;
+ private boolean mDistributeEvenly;
+
+ private ViewPager mViewPager;
+ private SparseArray<String> mContentDescriptions = new SparseArray<String>();
+ private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
+
+ private final SlidingTabStrip mTabStrip;
+
+ public SlidingTabLayout(Context context) {
+ this(context, null);
+ }
+
+ public SlidingTabLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ // Disable the Scroll Bar
+ setHorizontalScrollBarEnabled(false);
+ // Make sure that the Tab Strips fills this View
+ setFillViewport(true);
+
+ mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
+
+ mTabStrip = new SlidingTabStrip(context);
+ addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ }
+
+ /**
+ * Set the custom {@link TabColorizer} to be used.
+ *
+ * If you only require simple custmisation then you can use
+ * {@link #setSelectedIndicatorColors(int...)} to achieve
+ * similar effects.
+ */
+ public void setCustomTabColorizer(TabColorizer tabColorizer) {
+ mTabStrip.setCustomTabColorizer(tabColorizer);
+ }
+
+ public void setDistributeEvenly(boolean distributeEvenly) {
+ mDistributeEvenly = distributeEvenly;
+ }
+
+ /**
+ * Sets the colors to be used for indicating the selected tab. These colors are treated as a
+ * circular array. Providing one color will mean that all tabs are indicated with the same color.
+ */
+ public void setSelectedIndicatorColors(int... colors) {
+ mTabStrip.setSelectedIndicatorColors(colors);
+ }
+
+ /**
+ * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
+ * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
+ * that the layout can update it's scroll position correctly.
+ *
+ * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
+ */
+ public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
+ mViewPagerPageChangeListener = listener;
+ }
+
+ /**
+ * Set the custom layout to be inflated for the tab views.
+ *
+ * @param layoutResId Layout id to be inflated
+ * @param textViewId id of the {@link TextView} in the inflated view
+ */
+ public void setCustomTabView(int layoutResId, int textViewId) {
+ mTabViewLayoutId = layoutResId;
+ mTabViewTextViewId = textViewId;
+ }
+
+ /**
+ * Sets the associated view pager. Note that the assumption here is that the pager content
+ * (number of tabs and tab titles) does not change after this call has been made.
+ */
+ public void setViewPager(ViewPager viewPager) {
+ mTabStrip.removeAllViews();
+
+ mViewPager = viewPager;
+ if (viewPager != null) {
+ viewPager.setOnPageChangeListener(new InternalViewPagerListener());
+ populateTabStrip();
+ }
+ }
+
+ /**
+ * Create a default view to be used for tabs. This is called if a custom tab view is not set via
+ * {@link #setCustomTabView(int, int)}.
+ */
+ protected TextView createDefaultTabView(Context context) {
+ TextView textView = new TextView(context);
+ textView.setGravity(Gravity.CENTER);
+ textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
+ textView.setTypeface(Typeface.DEFAULT_BOLD);
+ textView.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+
+ TypedValue outValue = new TypedValue();
+ getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
+ outValue, true);
+ textView.setBackgroundResource(outValue.resourceId);
+ textView.setAllCaps(true);
+
+ int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
+ textView.setPadding(padding, padding, padding, padding);
+
+ return textView;
+ }
+
+ private void populateTabStrip() {
+ final PagerAdapter adapter = mViewPager.getAdapter();
+ final View.OnClickListener tabClickListener = new TabClickListener();
+
+ for (int i = 0; i < adapter.getCount(); i++) {
+ View tabView = null;
+ TextView tabTitleView = null;
+
+ if (mTabViewLayoutId != 0) {
+ // If there is a custom tab view layout id set, try and inflate it
+ tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
+ false);
+ tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
+ }
+
+ if (tabView == null) {
+ tabView = createDefaultTabView(getContext());
+ }
+
+ if (tabTitleView == null && TextView.class.isInstance(tabView)) {
+ tabTitleView = (TextView) tabView;
+ }
+
+ if (mDistributeEvenly) {
+ LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
+ lp.width = 0;
+ lp.weight = 1;
+ }
+
+ tabTitleView.setText(adapter.getPageTitle(i));
+ tabView.setOnClickListener(tabClickListener);
+ String desc = mContentDescriptions.get(i, null);
+ if (desc != null) {
+ tabView.setContentDescription(desc);
+ }
+
+ mTabStrip.addView(tabView);
+ if (i == mViewPager.getCurrentItem()) {
+ tabView.setSelected(true);
+ }
+ }
+ }
+
+ public void setContentDescription(int i, String desc) {
+ mContentDescriptions.put(i, desc);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ if (mViewPager != null) {
+ scrollToTab(mViewPager.getCurrentItem(), 0);
+ }
+ }
+
+ private void scrollToTab(int tabIndex, int positionOffset) {
+ final int tabStripChildCount = mTabStrip.getChildCount();
+ if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
+ return;
+ }
+
+ View selectedChild = mTabStrip.getChildAt(tabIndex);
+ if (selectedChild != null) {
+ int targetScrollX = selectedChild.getLeft() + positionOffset;
+
+ if (tabIndex > 0 || positionOffset > 0) {
+ // If we're not at the first child and are mid-scroll, make sure we obey the offset
+ targetScrollX -= mTitleOffset;
+ }
+
+ scrollTo(targetScrollX, 0);
+ }
+ }
+
+ private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
+ private int mScrollState;
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ int tabStripChildCount = mTabStrip.getChildCount();
+ if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
+ return;
+ }
+
+ mTabStrip.onViewPagerPageChanged(position, positionOffset);
+
+ View selectedTitle = mTabStrip.getChildAt(position);
+ int extraOffset = (selectedTitle != null)
+ ? (int) (positionOffset * selectedTitle.getWidth())
+ : 0;
+ scrollToTab(position, extraOffset);
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
+ positionOffsetPixels);
+ }
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ mScrollState = state;
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageScrollStateChanged(state);
+ }
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
+ mTabStrip.onViewPagerPageChanged(position, 0f);
+ scrollToTab(position, 0);
+ }
+ for (int i = 0; i < mTabStrip.getChildCount(); i++) {
+ mTabStrip.getChildAt(i).setSelected(position == i);
+ }
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageSelected(position);
+ }
+ }
+
+ }
+
+ private class TabClickListener implements View.OnClickListener {
+ @Override
+ public void onClick(View v) {
+ for (int i = 0; i < mTabStrip.getChildCount(); i++) {
+ if (v == mTabStrip.getChildAt(i)) {
+ mViewPager.setCurrentItem(i);
+ return;
+ }
+ }
+ }
+ }
+
+}
diff --git a/WordPress/src/main/java/org/wordpress/android/widgets/SlidingTabStrip.java b/WordPress/src/main/java/org/wordpress/android/widgets/SlidingTabStrip.java
new file mode 100644
index 000000000..a082065c2
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/widgets/SlidingTabStrip.java
@@ -0,0 +1,171 @@
+/*
+<<<<<<< Updated upstream
+ * Copyright (C) 2013 The Android Open Source Project
+=======
+ * Copyright 2014 Google Inc. All rights reserved.
+>>>>>>> Stashed changes
+ *
+ * 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 org.wordpress.android.widgets;
+import android.R;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.LinearLayout;
+
+class SlidingTabStrip extends LinearLayout {
+
+ private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 0;
+ private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
+ private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 3;
+ private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
+
+ private final int mBottomBorderThickness;
+ private final Paint mBottomBorderPaint;
+
+ private final int mSelectedIndicatorThickness;
+ private final Paint mSelectedIndicatorPaint;
+
+ private final int mDefaultBottomBorderColor;
+
+ private int mSelectedPosition;
+ private float mSelectionOffset;
+
+ private SlidingTabLayout.TabColorizer mCustomTabColorizer;
+ private final SimpleTabColorizer mDefaultTabColorizer;
+
+ SlidingTabStrip(Context context) {
+ this(context, null);
+ }
+
+ SlidingTabStrip(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setWillNotDraw(false);
+
+ final float density = getResources().getDisplayMetrics().density;
+
+ TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, true);
+ final int themeForegroundColor = outValue.data;
+
+ mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
+ DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
+
+ mDefaultTabColorizer = new SimpleTabColorizer();
+ mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
+
+ mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
+ mBottomBorderPaint = new Paint();
+ mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
+
+ mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
+ mSelectedIndicatorPaint = new Paint();
+ }
+
+ void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
+ mCustomTabColorizer = customTabColorizer;
+ invalidate();
+ }
+
+ void setSelectedIndicatorColors(int... colors) {
+ // Make sure that the custom colorizer is removed
+ mCustomTabColorizer = null;
+ mDefaultTabColorizer.setIndicatorColors(colors);
+ invalidate();
+ }
+
+ void onViewPagerPageChanged(int position, float positionOffset) {
+ mSelectedPosition = position;
+ mSelectionOffset = positionOffset;
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ final int height = getHeight();
+ final int childCount = getChildCount();
+ final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
+ ? mCustomTabColorizer
+ : mDefaultTabColorizer;
+
+ // Thick colored underline below the current selection
+ if (childCount > 0) {
+ View selectedTitle = getChildAt(mSelectedPosition);
+ int left = selectedTitle.getLeft();
+ int right = selectedTitle.getRight();
+ int color = tabColorizer.getIndicatorColor(mSelectedPosition);
+
+ if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
+ int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
+ if (color != nextColor) {
+ color = blendColors(nextColor, color, mSelectionOffset);
+ }
+
+ // Draw the selection partway between the tabs
+ View nextTitle = getChildAt(mSelectedPosition + 1);
+ left = (int) (mSelectionOffset * nextTitle.getLeft() +
+ (1.0f - mSelectionOffset) * left);
+ right = (int) (mSelectionOffset * nextTitle.getRight() +
+ (1.0f - mSelectionOffset) * right);
+ }
+
+ mSelectedIndicatorPaint.setColor(color);
+
+ canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
+ height, mSelectedIndicatorPaint);
+ }
+
+ // Thin underline along the entire bottom edge
+ canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
+ }
+
+ /**
+ * Set the alpha value of the {@code color} to be the given {@code alpha} value.
+ */
+ private static int setColorAlpha(int color, byte alpha) {
+ return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
+ }
+
+ /**
+ * Blend {@code color1} and {@code color2} using the given ratio.
+ *
+ * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
+ * 0.0 will return {@code color2}.
+ */
+ private static int blendColors(int color1, int color2, float ratio) {
+ final float inverseRation = 1f - ratio;
+ float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
+ float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
+ float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
+ return Color.rgb((int) r, (int) g, (int) b);
+ }
+
+ private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
+ private int[] mIndicatorColors;
+
+ @Override
+ public final int getIndicatorColor(int position) {
+ return mIndicatorColors[position % mIndicatorColors.length];
+ }
+
+ void setIndicatorColors(int... colors) {
+ mIndicatorColors = colors;
+ }
+ }
+}
diff --git a/WordPress/src/main/res/color/tab_text_color.xml b/WordPress/src/main/res/color/tab_text_color.xml
new file mode 100644
index 000000000..e265ce6d1
--- /dev/null
+++ b/WordPress/src/main/res/color/tab_text_color.xml
@@ -0,0 +1,5 @@
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@color/tab_text_selected" android:state_selected="true" />
+ <item android:color="@color/tab_text_normal" />
+</selector>
diff --git a/WordPress/src/main/res/layout/reader_activity_subs.xml b/WordPress/src/main/res/layout/reader_activity_subs.xml
index a0dc43805..127739f6a 100644
--- a/WordPress/src/main/res/layout/reader_activity_subs.xml
+++ b/WordPress/src/main/res/layout/reader_activity_subs.xml
@@ -21,9 +21,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
+ android:background="@color/tab_background"
android:paddingBottom="@dimen/margin_large"
android:paddingTop="@dimen/margin_large"
- android:textAppearance="@style/ReaderPagerTabStripText" />
+ android:textAppearance="@style/ReaderTabStripTextAppearance" />
</android.support.v4.view.ViewPager>
diff --git a/WordPress/src/main/res/layout/tab_text.xml b/WordPress/src/main/res/layout/tab_text.xml
new file mode 100644
index 000000000..c315e8aed
--- /dev/null
+++ b/WordPress/src/main/res/layout/tab_text.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<org.wordpress.android.widgets.WPTextView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/text_tab"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/toolbar_height"
+ android:background="?android:selectableItemBackground"
+ android:gravity="center"
+ android:paddingLeft="@dimen/margin_large"
+ android:paddingRight="@dimen/margin_large"
+ android:textAllCaps="true"
+ android:textColor="@color/tab_text_color"
+ android:textSize="@dimen/text_sz_medium"
+ android:textStyle="bold"
+ tools:text="text_tab" /> \ No newline at end of file
diff --git a/WordPress/src/main/res/layout/theme_browser_activity.xml b/WordPress/src/main/res/layout/theme_browser_activity.xml
index a73bff1ff..ccf5040d0 100644
--- a/WordPress/src/main/res/layout/theme_browser_activity.xml
+++ b/WordPress/src/main/res/layout/theme_browser_activity.xml
@@ -1,23 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/theme_browser_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical" >
+ android:orientation="vertical">
- <org.wordpress.android.ui.HorizontalTabView
- android:id="@+id/horizontalTabView1"
+ <org.wordpress.android.widgets.SlidingTabLayout
+ android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:fillViewport="true"
- android:scrollbars="none" />
+ android:background="@color/tab_background" />
<android.support.v4.view.ViewPager
android:id="@+id/theme_browser_pager"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_below="@id/horizontalTabView1" />
+ android:layout_height="match_parent" />
-</RelativeLayout> \ No newline at end of file
+</LinearLayout> \ No newline at end of file
diff --git a/WordPress/src/main/res/values/colors.xml b/WordPress/src/main/res/values/colors.xml
index e6ea42d03..2eaa450a8 100644
--- a/WordPress/src/main/res/values/colors.xml
+++ b/WordPress/src/main/res/values/colors.xml
@@ -55,10 +55,11 @@
<color name="theme_details_premium">#B0710E</color>
<color name="theme_feature_text">#555555</color>
- <!-- Horizontal Tab View colors -->
- <color name="tab_divider">#565656</color>
- <color name="tab_background">#363636</color>
- <color name="tab_text">@color/white</color>
+ <!-- Tab Strip colors -->
+ <color name="tab_background">@color/color_primary</color>
+ <color name="tab_text_normal">@color/blue_light</color>
+ <color name="tab_text_selected">@color/white</color>
+ <color name="tab_indicator">@color/blue_light</color>
<!-- Stats bar graph colors -->
<color name="stats_bar_graph_views">#7CABC1</color>
diff --git a/WordPress/src/main/res/values/reader_styles.xml b/WordPress/src/main/res/values/reader_styles.xml
index d16c4a4e9..af4872748 100644
--- a/WordPress/src/main/res/values/reader_styles.xml
+++ b/WordPress/src/main/res/values/reader_styles.xml
@@ -176,11 +176,11 @@
<!-- progress bars -->
<style name="ReaderProgressBar" parent="@android:style/Widget.Holo.Light.ProgressBar" />
- <!-- tab strip text appearance -->
- <style name="ReaderPagerTabStripText">
+ <style name="ReaderTabStripTextAppearance">
<item name="android:textSize">@dimen/text_sz_medium</item>
<item name="android:textStyle">bold</item>
- <item name="android:textColor">@color/white</item>
+ <item name="android:textColor">@color/tab_text_color</item>
<item name="android:textAllCaps">true</item>
+ <item name="android:gravity">center</item>
</style>
</resources> \ No newline at end of file
diff --git a/WordPress/src/main/res/values/styles.xml b/WordPress/src/main/res/values/styles.xml
index ccab0415a..2a2a87671 100644
--- a/WordPress/src/main/res/values/styles.xml
+++ b/WordPress/src/main/res/values/styles.xml
@@ -338,4 +338,5 @@
<style name="WordPress.SwipeToRefresh">
<item name="refreshIndicatorColor">@color/blue_new_kid</item>
</style>
+
</resources> \ No newline at end of file