TabLayout是AndroID 的Material Design包中的一个控件,可以和V4包中的VIEwPager搭配产生一个联动的效果。这里我自定义了一个滑块能够跟随TabLayout进行滑动选择的SlIDerLayout。效果见下图(白色方框):
下面是SlIDerLayout的源码:
import androID.content.Context;import androID.content.res.TypedArray;import androID.graphics.drawable.Drawable;import androID.support.design.Widget.TabLayout;import androID.util.AttributeSet;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.ImageVIEw;import androID.Widget.linearLayout;import java.lang.ref.WeakReference;/*** Created by yyw on 2016/4/28.* 一个用来显示当前的index的滑块*/public class SlIDerLayout extends linearLayout {private int totalNum = 0;private ImageVIEw mSlIDer;private Drawable mSlIDerImage;private WeakReference<TabLayout> mTabLayoutRef;public SlIDerLayout(Context context) {this(context,null);}public SlIDerLayout(Context context,AttributeSet attrs) {this(context,attrs,0);}public SlIDerLayout(Context context,AttributeSet attrs,int defStyleAttr) {super(context,defStyleAttr);TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.SlIDerLayout);mSlIDerImage = array.getDrawable(R.styleable.SlIDerLayout_slIDer_pic);if (mSlIDerImage == null) {mSlIDerImage = context.getResources().getDrawable(R.drawable.slIDer);}array.recycle();init(context);}private voID init(Context context) {mSlIDer = new ImageVIEw(context);mSlIDer.setimageDrawable(mSlIDerImage);addVIEw(mSlIDer,VIEwGroup.LayoutParams.WRAP_CONTENT,VIEwGroup.LayoutParams.WRAP_CONTENT);}@OverrIDeprotected voID onSizeChanged(int w,int h,int olDW,int oldh) {super.onSizeChanged(w,h,olDW,oldh);resetSlIDer();}/*** 重新设置滑块*/private voID resetSlIDer() {if (getorIEntation() == HORIZONTAL) {resetHorizontalSlIDer();}}/*** 重置水平方向的滑块大小*/private voID resetHorizontalSlIDer() {if (mTabLayoutRef == null) return;TabLayout tabLayout = mTabLayoutRef.get();if (tabLayout == null) return;linearLayout mTabStrip = (linearLayout) tabLayout.getChildAt(0);totalNum = mTabStrip.getChildCount();if (totalNum > 0) {VIEw firstVIEw = mTabStrip.getChildAt(0);int wIDth = firstVIEw.getMeasureDWIDth();resetSlIDer(wIDth);}}//重新设置滑块的大小private voID resetSlIDer(int wIDth) {LayoutParams params = (LayoutParams) mSlIDer.getLayoutParams();params.wIDth = wIDth;//重新设置滑块的大小params.height = getHeight() / 2;params.gravity = Gravity.CENTER_VERTICAL;mSlIDer.setpadding(wIDth / 10,wIDth / 10,0);//设置VIEw的左右向内收缩mSlIDer.setLayoutParams(params);}public voID setupWithTabLayout(TabLayout tabLayout) {mTabLayoutRef = new WeakReference<>(tabLayout);resetHorizontalSlIDer();}public static final String TAG = SlIDerLayout.class.getname();public static class SlIDerOnPagechangelistener extends TabLayout.TabLayoutOnPagechangelistener {private final WeakReference<SlIDerLayout> mSlIDerLayoutRef;public SlIDerOnPagechangelistener(TabLayout tabLayout,SlIDerLayout layout) {super(tabLayout);mSlIDerLayoutRef = new WeakReference<SlIDerLayout>(layout);layout.setupWithTabLayout(tabLayout);}@OverrIDepublic voID onPageScrollStateChanged(int state) {super.onPageScrollStateChanged(state);}@OverrIDepublic voID onPageScrolled(int position,float positionOffset,int positionOffsetPixels) {super.onPageScrolled(position,positionOffset,positionOffsetPixels);final SlIDerLayout layout = mSlIDerLayoutRef.get();if (layout != null) {layout.setScrollposition(position,positionOffset);}}}/*** 把滑块滑动到指定的位置** @param position 当前位置* @param positionOffset 滑动到下一个或上一个位置比例*/private voID setScrollposition(int position,float positionOffset) {final int roundedposition = Math.round(position + positionOffset);if (roundedposition < 0 || roundedposition >= totalNum) {return;}float scrollX = calculateScrollXForTab(position,positionOffset);scrollTo((int) scrollX,0);}/*** 计算滑块需要滑动的距离** @param position 当前选择的位置* @param positionOffset 滑动位置的百分百* @return 滑动的距离*/private int calculateScrollXForTab(int position,float positionOffset) {TabLayout tabLayout = mTabLayoutRef.get();if (tabLayout == null) return 0;linearLayout mTabStrip = (linearLayout) tabLayout.getChildAt(0);if (mTabStrip == null) return 0;//当前选择的VIEwfinal VIEw selectedChild = mTabStrip.getChildAt(position);//下一个VIEwfinal VIEw nextChild = position + 1 < mTabStrip.getChildCount()? mTabStrip.getChildAt(position + 1): null;//当前选择的VIEw的宽度final int selecteDWIDth = selectedChild != null ? selectedChild.getWIDth() : 0;//下一个VIEw的宽度final int nextWIDth = nextChild != null ? nextChild.getWIDth() : 0;//当前选择的VIEw的左边位置,vIEw的方位final int left = selectedChild != null ? selectedChild.getleft() : 0;//计算滑块需要滑动的距离,左 + ,右 - ;int scrollX = -(left + ((int) ((selecteDWIDth + nextWIDth) * positionOffset * 0.5f)));if (tabLayout.getTabMode() == TabLayout.MODE_SCRolLABLE) {//当为滑动模式的时候TabLayout会有水平方向的滑动scrollX += tabLayout.getScrollX();//计算在TabLayout有滑动的时候,滑块相对的滑动距离}return scrollX;}}
其中比较关键的一个类是SlIDerOnPagechangelistener 这个类继承的TabLayout.TabLayoutOnPagechangelistener类这个类我们看源码(下面)这个是监听VIEwPager滑动选择的一个接口。我们要做的就是在这个类基础上进行扩展让SlIDerLayout也能监听到VIEwPager的滑动。
public static class TabLayoutOnPagechangelistener implements VIEwPager.OnPagechangelistener {private final WeakReference<TabLayout> mTabLayoutRef;private int mPrevIoUsScrollState;private int mScrollState;public TabLayoutOnPagechangelistener(TabLayout tabLayout) {mTabLayoutRef = new WeakReference<>(tabLayout);}@OverrIDepublic voID onPageScrollStateChanged(int state) {mPrevIoUsScrollState = mScrollState;mScrollState = state;}@OverrIDepublic voID onPageScrolled(int position,int positionOffsetPixels) {//省略}}@OverrIDepublic voID onPageSelected(int position) {//省略}private voID reset() {mPrevIoUsScrollState = mScrollState = SCRolL_STATE_IDLE;}}
计算每次SlIDerLayout需要滑动的距离的方法是calculateScrollXForTab(int position,float positionOffset)(详细看源码)根据监听到的VIEwPager滑动进行相关的计算并滑动SlIDerLayout
应用的时候一定要注意vIEwPager.setonPagechangelistener(new SlIDerLayout.SlIDerOnPagechangelistener(mTabLayout,layout));要在mTabLayout.setupWithVIEwPager(vIEwPager);之后调用:
public class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getname();@OverrIDeprotected voID onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentVIEw(R.layout.activity_main);final TabLayout mTabLayout = (TabLayout) findVIEwByID(R.ID.tab_layout);VIEwPager vIEwPager = (VIEwPager) findVIEwByID(R.ID.vp);SlIDerLayout layout = (SlIDerLayout) findVIEwByID(R.ID.slIDer_layout);vIEwPager.setAdapter(new MVIEwPagerAdapter(getSupportFragmentManager()));mTabLayout.setupWithVIEwPager(vIEwPager);//方法一定要在mTabLayout.setupWithVIEwPager(vIEwPager)之后不然没有效果vIEwPager.setonPagechangelistener(new SlIDerLayout.SlIDerOnPagechangelistener(mTabLayout,layout));}class MVIEwPagerAdapter extends FragmentPagerAdapter {public final String[] names = new String[]{"音乐","电影","电视","综艺","直播","音乐","直播"};public MVIEwPagerAdapter(FragmentManager fm) {super(fm);}@OverrIDepublic Fragment getItem(int position) {return BlankFragment.newInstance("param1","param2");}@OverrIDepublic int getCount() {return 10;}@OverrIDepublic CharSequence getPageTitle(int position) {return names[position];}}}
布局:
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"xmlns:app="http://schemas.androID.com/apk/res-auto"androID:layout_wIDth="match_parent"androID:layout_height="match_parent"androID:orIEntation="vertical"><FrameLayoutandroID:layout_wIDth="match_parent"androID:background="@color/cardvIEw_dark_background"androID:layout_height="50dp"><com.example.yyw.waterripple.SlIDerLayoutandroID:ID="@+ID/slIDer_layout"androID:layout_wIDth="match_parent"androID:layout_height="50dp"app:slIDer_pic="@drawable/slIDer"androID:orIEntation="horizontal" /><androID.support.design.Widget.TabLayoutandroID:ID="@+ID/tab_layout"androID:layout_wIDth="match_parent"androID:layout_height="50dp"app:tabGravity="center"app:tabMode="scrollable"app:tabSelectedTextcolor="#ff0000"app:tabTextcolor="#ffffff" /></FrameLayout><androID.support.v4.vIEw.VIEwPagerandroID:ID="@+ID/vp"androID:layout_wIDth="match_parent"androID:layout_height="match_parent" /></linearLayout><declare-styleable name="SlIDerLayout"><attr name="slIDer_pic" format="reference" /></declare-styleable><?xml version="1.0" enCoding="utf-8"?><shape xmlns:androID="http://schemas.androID.com/apk/res/androID"androID:shape="rectangle"><cornersandroID:topLefTradius="10dp"androID:topRighTradius="10dp"androID:bottomLefTradius="10dp"androID:bottomrighTradius="10dp" /><solID androID:color="#ffffff" /></shape>
以上所述是小编给大家介绍的AndroID 中TabLayout自定义选择背景滑块的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
总结以上是内存溢出为你收集整理的Android 中TabLayout自定义选择背景滑块的实例代码全部内容,希望文章能够帮你解决Android 中TabLayout自定义选择背景滑块的实例代码所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)