diff --git a/demo/src/main/java/com/ogaclejapan/smarttablayout/demo/Demo.java b/demo/src/main/java/com/ogaclejapan/smarttablayout/demo/Demo.java index 5d1bf08..8c7d52a 100755 --- a/demo/src/main/java/com/ogaclejapan/smarttablayout/demo/Demo.java +++ b/demo/src/main/java/com/ogaclejapan/smarttablayout/demo/Demo.java @@ -25,6 +25,8 @@ public int[] tabs() { } }, + AUTOSELECT_ON_SCROLL(R.string.demo_title_autoselect_on_scroll, R.layout.demo_autoselect_on_scroll), + ALWAYS_IN_CENTER(R.string.demo_title_always_in_center, R.layout.demo_always_in_center), CUSTOM_TAB(R.string.demo_title_custom_tab_text, R.layout.demo_custom_tab_text), diff --git a/demo/src/main/res/layout/demo_autoselect_on_scroll.xml b/demo/src/main/res/layout/demo_autoselect_on_scroll.xml new file mode 100755 index 0000000..01600ac --- /dev/null +++ b/demo/src/main/res/layout/demo_autoselect_on_scroll.xml @@ -0,0 +1,18 @@ + + + diff --git a/demo/src/main/res/values/strings.xml b/demo/src/main/res/values/strings.xml index 6903499..4b277c1 100755 --- a/demo/src/main/res/values/strings.xml +++ b/demo/src/main/res/values/strings.xml @@ -10,6 +10,7 @@ Basic(Title Offset Auto Center) Smart Indicator Distribute Evenly + Auto Select On Scroll Always In Center Custom Tab Text Custom Tab Margin (since 1.2~) diff --git a/library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabLayout.java b/library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabLayout.java index b587dbc..0ed14ac 100755 --- a/library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabLayout.java +++ b/library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabLayout.java @@ -26,9 +26,11 @@ import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.DisplayMetrics; +import android.util.SparseIntArray; import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.HorizontalScrollView; @@ -85,6 +87,8 @@ public class SmartTabLayout extends HorizontalScrollView { private InternalTabClickListener internalTabClickListener; private OnTabClickListener onTabClickListener; private boolean distributeEvenly; + private boolean autoSelectOnScroll; + private SparseIntArray offsetArray = new SparseIntArray(); public SmartTabLayout(Context context) { this(context, null); @@ -114,6 +118,7 @@ public SmartTabLayout(Context context, AttributeSet attrs, int defStyle) { int customTabLayoutId = NO_ID; int customTabTextViewId = NO_ID; boolean clickable = TAB_CLICKABLE; + boolean autoSelectOnScroll = false; int titleOffset = (int) (TITLE_OFFSET_DIPS * density); TypedArray a = context.obtainStyledAttributes( @@ -140,6 +145,8 @@ public SmartTabLayout(Context context, AttributeSet attrs, int defStyle) { R.styleable.stl_SmartTabLayout_stl_clickable, clickable); titleOffset = a.getLayoutDimension( R.styleable.stl_SmartTabLayout_stl_titleOffset, titleOffset); + autoSelectOnScroll = a.getBoolean( + R.styleable.stl_SmartTabLayout_stl_autoSelectOnScroll, autoSelectOnScroll); a.recycle(); this.titleOffset = titleOffset; @@ -153,6 +160,7 @@ public SmartTabLayout(Context context, AttributeSet attrs, int defStyle) { this.tabViewTextMinWidth = textMinWidth; this.internalTabClickListener = clickable ? new InternalTabClickListener() : null; this.distributeEvenly = distributeEvenly; + this.autoSelectOnScroll = autoSelectOnScroll; if (customTabLayoutId != NO_ID) { setCustomTabView(customTabLayoutId, customTabTextViewId); @@ -165,6 +173,11 @@ public SmartTabLayout(Context context, AttributeSet attrs, int defStyle) { "'distributeEvenly' and 'indicatorAlwaysInCenter' both use does not support"); } + if (autoSelectOnScroll && !tabStrip.isIndicatorAlwaysInCenter()) { + throw new UnsupportedOperationException( + "'autoSelectOnScroll' and 'indicatorAlwaysInCenter' both should be enabled"); + } + // Make sure that the Tab Strips fills this View setFillViewport(!tabStrip.isIndicatorAlwaysInCenter()); @@ -172,6 +185,27 @@ public SmartTabLayout(Context context, AttributeSet attrs, int defStyle) { } + @Override + public boolean onTouchEvent(MotionEvent ev) { + if (autoSelectOnScroll) { + if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) { + int scrollX = getScrollX(); + int currPos = viewPager.getCurrentItem(); + int featureWidth = getTabAt(currPos).getMeasuredWidth(); + // Calculate the compensation to add/remove to the scroll for tabs with different widths + for (int i = 0; i < currPos; i++) { + scrollX += (featureWidth - getTabAt(i).getMeasuredWidth()); + } + int activeTab = ((scrollX + (featureWidth / 2)) / featureWidth); + int scrollTo = offsetArray.get(activeTab); + smoothScrollTo(scrollTo, 0); + viewPager.setCurrentItem(activeTab); + return true; + } + } + return super.onTouchEvent(ev); + } + @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); @@ -201,6 +235,14 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { if (changed && viewPager != null) { scrollToTab(viewPager.getCurrentItem(), 0); } + if (autoSelectOnScroll) { + int totalWidth = 0; + offsetArray.put(0, totalWidth); + for (int i = 1; i < tabStrip.getChildCount(); i++) { + totalWidth += getTabAt(i - 1).getMeasuredWidth(); + offsetArray.put(i, totalWidth); + } + } } /** @@ -299,7 +341,7 @@ public void setOnTabClickListener(OnTabClickListener 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 android.widget.TextView} in the inflated view + * @param textViewId id of the {@link TextView} in the inflated view */ public void setCustomTabView(int layoutResId, int textViewId) { tabProvider = new SimpleTabProvider(getContext(), layoutResId, textViewId); diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index 34891e5..47684f1 100755 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -41,5 +41,6 @@ +