1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 自定义TabLayout

自定义TabLayout

时间:2023-03-28 23:18:12

相关推荐

自定义TabLayout

前言

系统自带的Tablayout用的也不错但是有些功能还不能满足我们这边开发,所以我这边自定义了一个tablayout提供了自定义tab线的长度以及,移动速度,以及禁止某个滑动(tablayout基本功能也提供了)

效果图

QQ0327-165412-HD(1).gif

实现步骤

构造方法添加子控件

添加一些xml定义的属性

public MyIndicator(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.setGravity(Gravity.CENTER_VERTICAL);this.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.Indicator, 0, 0);mColor = array.getColor(R.styleable.Indicator_indicatorColor, Color.RED);mList = getContext().getResources().getStringArray(array.getResourceId(R.styleable.Indicator_array, 0));mTextNomal = array.getInteger(R.styleable.Indicator_text_nomal_size, 12);mTextPress = array.getInteger(R.styleable.Indicator_text_press_size, 13);mText_Nomal = array.getColor(R.styleable.Indicator_text_nomal_color, Color.GRAY);mText_Press = array.getColor(R.styleable.Indicator_text_press_color, Color.BLACK);mSelected = array.getInteger(R.styleable.Indicator_selected, 0);isFull = array.getBoolean(R.styleable.Indicator_isFull, false);mAnimationTime = array.getInteger(R.styleable.Indicator_speed, 300);mBai = array.getFloat(R.styleable.Indicator_multiply, (float) 1.2);mHeight = array.getInteger(R.styleable.Indicator_line_hegith, 5);for (int i = 0; i < mList.length; i++) {mListTitle.add(mList[i]);}array.recycle();}

onLayout初始化布局

添加控件

@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);if (!mIsCheck) {mIsCheck = true;initView();}}

添加textview以及线

/*** 初始化布局*/private void initView() {measure(0, 0);//获取每个textview布局所占的宽度mContWidth = getWidth() / mListTitle.size();//添加线mLine = new View(getContext());addView(mLine);int mWeight;if (isFull) {mWeight = mContWidth;} else {mWeight = (int) (setLineLength(mListTitle.get(mSelected)) * mBai);if (mWeight > mContWidth) {mWeight = mContWidth;}}//设置线的基本属性LayoutParams mLayoutParams1 = new LayoutParams(mWeight, mHeight);mLayoutParams1.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);mLine.setLayoutParams(mLayoutParams1);mLine.setBackgroundColor(mColor);//获取上一次所在位置mEndAddress = mContWidth * mSelected + (mContWidth - mWeight) / 2;//添加textviewfor (int i = 0; i < mListTitle.size(); i++) {addTextView(i);}//初始化点击事件setListener();}

/*** 添加textview*/private void addTextView(int i) {//初始化textviewTextView textView = new TextView(getContext());textView.setText(mListTitle.get(i));//设置textview基本属性LayoutParams mLayoutParams = new LayoutParams(mContWidth, LayoutParams.MATCH_PARENT);mLayoutParams.leftMargin = mContWidth * i;mLayoutParams.addRule(CENTER_VERTICAL);textView.setLayoutParams(mLayoutParams);textView.setGravity(Gravity.CENTER);if (i == mSelected) {textView.setTextColor(mText_Press);textView.setTextSize(mTextPress);} else {textView.setTextColor(mText_Nomal);textView.setTextSize(mTextNomal);}//添加textview到布局mTextList.add(textView);addView(textView);}

动画

动画就简单了直接一个移动动画就好了

/*** 动画** @param statX 开始位置* @param endX 结束位置*/private void setAnimation(int statX, int endX) {AnimationSet mSet = new AnimationSet(true);TranslateAnimation translate1 = new TranslateAnimation(statX, endX, 0, 0);mSet.addAnimation(translate1);mSet.setFillAfter(true);mSet.setDuration(mAnimationTime);mLine.startAnimation(mSet);}

修改下标位置

计算修改下标的位置

/*** 改变下标** @param position*/public void setChanger(int position) {//改为默认字体颜色修改选中字体颜色resetColor();mTextList.get(position).setTextColor(mText_Press);mTextList.get(position).setTextSize(mTextPress);mSelected = position;int mWeight;if (isFull) {mWeight = mContWidth;} else {mWeight = (int) (setLineLength(mListTitle.get(mSelected)) * mBai);if (mWeight > mContWidth) {mWeight = mContWidth;}}/*** 计算当前选择textview的X点位置*/int way = mContWidth * mSelected + (mContWidth - mWeight) / 2;LayoutParams mLayoutParams = new LayoutParams(mWeight, mHeight);mLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);mLine.setLayoutParams(mLayoutParams);setAnimation(mEndAddress, way);mEndAddress = way;this.mNowPosition = position;}

XML部分属性

线的颜色 : indicatorColor (默认red)

textview显示数组 :array

字体默认颜色:text_nomal_color (默认gray)

字体选中颜色:text_press_color (默认black)

字体默认大小:text_press_color (默认12)

字体选中大小:text_press_size (默认13)

默认选中:selected (默认0)

线是否铺满:isFull (默认false)

移动速度:speed (默认300)

线是字体的倍数:multiply (默认1.2)

线的高度: multiply (默认5)

<declare-styleable name="Indicator"><attr name="indicatorColor" format="color"/><attr name="array" format="integer"/><attr name="text_nomal_color" format="color"/><attr name="text_press_color" format="color"/><attr name="text_nomal_size" format="integer"/><attr name="text_press_size" format="integer"/><attr name="selected" format="integer"/><attr name="isFull" format="boolean"/><attr name="speed" format="integer"/><attr name="multiply" format="float"/><attr name="line_hegith" format="integer"/></declare-styleable>

自定义控件代码献上

JAVA代码

/*** Created by huangbo on 17/1/22.* 指示器*/public class MyIndicator extends RelativeLayout {/*** 线的颜色*/private int mColor;/*** 线的高度*/private int mHeight;/*** xml数组*/private String[] mList;/*** textview数组*/private List<TextView> mTextList = new ArrayList<>();/*** string数组*/private List<String> mListTitle = new ArrayList<>();/*** 默认字体大小*/private int mTextNomal;/*** 被选择字体大小*/private int mTextPress;/*** 默认字体颜色*/private int mText_Nomal;/*** 被选择的颜色*/private int mText_Press;/*** 每个格子个长度*/private int mContWidth;/*** 被选择的tab*/private int mSelected;/*** 底线*/private View mLine;/*** 是否或去过*/private boolean mIsCheck;/*** 字体的多少倍*/private float mBai;/*** 记录移动结束位置*/private int mEndAddress;/*** 禁止滑动表情下标*/private int mProhibitPisition = -1;/*** 动画时间*/private int mAnimationTime;/*** 当前选中*/private int mNowPosition;/*** 是否铺满*/private boolean isFull;public MyIndicator(Context context) {this(context, null);}public MyIndicator(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyIndicator(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.setGravity(Gravity.CENTER_VERTICAL);this.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.Indicator, 0, 0);mColor = array.getColor(R.styleable.Indicator_indicatorColor, Color.RED);mList = getContext().getResources().getStringArray(array.getResourceId(R.styleable.Indicator_array, 0));mTextNomal = array.getInteger(R.styleable.Indicator_text_nomal_size, 12);mTextPress = array.getInteger(R.styleable.Indicator_text_press_size, 13);mText_Nomal = array.getColor(R.styleable.Indicator_text_nomal_color, Color.GRAY);mText_Press = array.getColor(R.styleable.Indicator_text_press_color, Color.BLACK);mSelected = array.getInteger(R.styleable.Indicator_selected, 0);isFull = array.getBoolean(R.styleable.Indicator_isFull, false);mAnimationTime = array.getInteger(R.styleable.Indicator_speed, 300);mBai = array.getFloat(R.styleable.Indicator_multiply, (float) 1.2);mHeight = array.getInteger(R.styleable.Indicator_line_hegith, 5);for (int i = 0; i < mList.length; i++) {mListTitle.add(mList[i]);}array.recycle();}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);if (!mIsCheck) {mIsCheck = true;initView();}}/*** 初始化布局*/private void initView() {measure(0, 0);//获取每个textview布局所占的宽度mContWidth = getWidth() / mListTitle.size();//添加线mLine = new View(getContext());addView(mLine);int mWeight;if (isFull) {mWeight = mContWidth;} else {mWeight = (int) (setLineLength(mListTitle.get(mSelected)) * mBai);if (mWeight > mContWidth) {mWeight = mContWidth;}}//设置线的基本属性LayoutParams mLayoutParams1 = new LayoutParams(mWeight, mHeight);mLayoutParams1.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);mLine.setLayoutParams(mLayoutParams1);mLine.setBackgroundColor(mColor);//获取上一次所在位置mEndAddress = mContWidth * mSelected + (mContWidth - mWeight) / 2;//添加textviewfor (int i = 0; i < mListTitle.size(); i++) {addTextView(i);}//初始化点击事件setListener();}/*** 添加textview*/private void addTextView(int i) {//初始化textviewTextView textView = new TextView(getContext());textView.setText(mListTitle.get(i));//设置textview基本属性LayoutParams mLayoutParams = new LayoutParams(mContWidth, LayoutParams.MATCH_PARENT);mLayoutParams.leftMargin = mContWidth * i;mLayoutParams.addRule(CENTER_VERTICAL);textView.setLayoutParams(mLayoutParams);textView.setGravity(Gravity.CENTER);if (i == mSelected) {textView.setTextColor(mText_Press);textView.setTextSize(mTextPress);} else {textView.setTextColor(mText_Nomal);textView.setTextSize(mTextNomal);}//添加textview到布局mTextList.add(textView);addView(textView);}/*** 清空字体颜色*/private void resetColor() {for (int i = 0; i < mTextList.size(); i++) {mTextList.get(i).setTextColor(getContext().getResources().getColor(R.color.text_hint));}}/*** 点击tab事件*/private void setListener() {setAnimation(0, mEndAddress);for (int i = 0; i < mTextList.size(); i++) {final int finalI = i;mTextList.get(i).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (finalI != mSelected && mProhibitPisition != finalI) {setChanger(finalI);}if (mOnIndiacatorClickListener != null)mOnIndiacatorClickListener.onClick(finalI, v);}});}}/*** 动画** @param statX 开始位置* @param endX 结束位置*/private void setAnimation(int statX, int endX) {AnimationSet mSet = new AnimationSet(true);TranslateAnimation translate1 = new TranslateAnimation(statX, endX, 0, 0);mSet.addAnimation(translate1);mSet.setFillAfter(true);mSet.setDuration(mAnimationTime);mLine.startAnimation(mSet);}private OnIndiacatorClickListener mOnIndiacatorClickListener;/*** 计算下划线长度*/private int setLineLength(String mTextView) {return ConvertUtils.dp2px(mTextView.length() * mTextPress);}/*** 添加页面** @param charSequence*/public void add(CharSequence charSequence, int position) {removeAllViews();mTextList.clear();if (mListTitle.size() == position)mListTitle.set(position - 1, charSequence.toString());elsemListTitle.add(charSequence.toString());initView();}/*** 设置是否铺满*/public void setFull() {isFull = true;}/*** 设置监听** @param onIndiacatorClickListener*/public void setIndiacatorListener(OnIndiacatorClickListener onIndiacatorClickListener) {if (onIndiacatorClickListener != null) {this.mOnIndiacatorClickListener = onIndiacatorClickListener;}}/*** 设置禁止滑动页面** @param i*/public void setProhibitPositio(int i) {this.mProhibitPisition = i;}/*** 设置动画时间*/public void setAnimationTime(int time) {this.mAnimationTime = time;}/*** 外部监听*/public interface OnIndiacatorClickListener {void onClick(int position, View view);}/*** 改变下标** @param position*/public void setChanger(int position) {//改为默认字体颜色修改选中字体颜色resetColor();mTextList.get(position).setTextColor(mText_Press);mTextList.get(position).setTextSize(mTextPress);mSelected = position;int mWeight;if (isFull) {mWeight = mContWidth;} else {mWeight = (int) (setLineLength(mListTitle.get(mSelected)) * mBai);if (mWeight > mContWidth) {mWeight = mContWidth;}}/*** 计算当前选择textview的X点位置*/int way = mContWidth * mSelected + (mContWidth - mWeight) / 2;LayoutParams mLayoutParams = new LayoutParams(mWeight, mHeight);mLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);mLine.setLayoutParams(mLayoutParams);setAnimation(mEndAddress, way);mEndAddress = way;this.mNowPosition = position;}/*** 获取当前下标*/public int getPosition() {return mNowPosition;}}

XML基本使用代码

<.androiddemo.MyIndicatorandroid:id="@+id/my"android:layout_width="match_parent"android:layout_height="50dp"app:array="@array/tabs"app:indicatorColor="@color/btn_red"app:selected="0"app:text_nomal_color="@color/text_hint"app:text_nomal_size="12"app:text_press_color="@color/text_title"app:text_press_size="13"></.androiddemo.MyIndicator>

结语

客官看完肯定觉得非常简单,每个人的思路不一样实现的方式也有很多,如果觉得我的实现方式有问题或者好的实现方式可以给我留言,当然如果有什么特殊需求的话也可以留言给我,我帮你们提供相关需求,以后还会继续更新相关博客希望各位给一个支持

地址

项目github地址:GitHub

依赖

compile 'com.github.q1104133609:MyTabLayout:v0.0.1'

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。