Reputation: 2443
I have 12 items in android sliding tab layout + view pager. While sliding from left to right, selected tab should be center same as play store. Please help me how to do that. In my application active tab is always left of the screen.
Upvotes: 8
Views: 13870
Reputation: 1582
Had this problem as well. tabLayout provides only tabContentStart option, needed both sides:
public class CenteringTabLayout extends TabLayout {
public CenteringTabLayout(Context context) {
super(context);
}
public CenteringTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CenteringTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
View firstTab = ((ViewGroup)getChildAt(0)).getChildAt(0);
View lastTab = ((ViewGroup)getChildAt(0)).getChildAt(((ViewGroup)getChildAt(0)).getChildCount()-1);
ViewCompat.setPaddingRelative(getChildAt(0), (getWidth()/2) - (firstTab.getWidth()/2),0,(getWidth()/2) - (lastTab.getWidth()/2),0);
}
}
Upvotes: 2
Reputation: 2443
Google Has provided sample for sliding tab layout. But in the implementation of SlidingTabLayout class, it was not designed for center align the selected tab. I have modify the scroll method to make the selected/active tab center of the screen. Here is the code change:
Class Name: SlidingTabLayout
Line Number: 241, scrollToTab{}
Updated Method:
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 -= (getWidth()-selectedChild.getWidth())/2;
}
scrollTo(targetScrollX, 0);
}
}
Upvotes: 3
Reputation: 1238
My approach differs a bit of the Shripad Bhat solution, which bounce the tab at the end of the slide.
Here's my workaround...
Changes to onPageScrolled
method:
@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 selectedOffset = (selectedTitle == null) ? 0 : selectedTitle.getWidth();
int nextTitlePosition = position + 1;
View nextTitle = mTabStrip.getChildAt(nextTitlePosition);
int nextOffset = (nextTitle == null) ? 0 : nextTitle.getWidth();
int extraOffset = (int)(0.5F * (positionOffset * (float)(selectedOffset + nextOffset)));
scrollToTab(position, extraOffset);
if (mViewPagerPageChangeListener != null) {
mViewPagerPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
Changes to scrollToTab
method:
private int mLastScrollTo;
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 && selectedChild.getMeasuredWidth() != 0) {
int targetScrollX = ((positionOffset + selectedChild.getLeft()) - getWidth() / 2) + selectedChild.getWidth() / 2;
if (targetScrollX != mLastScrollTo) {
scrollTo(targetScrollX, 0);
mLastScrollTo = targetScrollX;
}
}
}
Upvotes: 13