Android换页指示器TabIndicator
来源:互联网 发布:淘宝天猫优惠券采集 编辑:程序博客网 时间:2024/06/06 08:03
一、看效果
二、实现原理
1、继承线性布局LinearLayout;
2、在测量方法onMeasure中,在原高度上基础上增加下划线高度:
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() + underlineHeight);}
3、在布局方法onLayout中,为下划线预留高度:
@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b - underlineHeight);}
@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int childCount = getChildCount();if (childCount <= 0 || currentTab < 0 || currentTab >= childCount) {return;}if (offset < -1) {offset = -1;}if (offset > 1) {offset = 1;}View child = getChildAt(currentTab);int underlineWidth = child.getWidth();int left = child.getLeft();int right = child.getRight();int bottom = getHeight() - getPaddingBottom();int top = bottom - underlineHeight;float offsetWidth = underlineWidth * offset;paint.setColor(underlineColor);canvas.drawRect(left + offsetWidth, top, right + offsetWidth, bottom, paint);}
注意,绘制方法中同时也实现下划线动态偏移的效果,后面可以看完整代码。
三、完整代码
在下述代码中,我们还给出了一个简单设置文本标签的快捷适配器。
import android.content.Context;import android.database.DataSetObserver;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.LinearLayout;import android.widget.TextView;public class TabIndicator extends LinearLayout {protected BaseAdapter adapter;private int underlineColor;private int underlineHeight;private Paint paint;private int currentTab = 0;private float offset = 0;public TabIndicator(Context context) {this(context, null);}public TabIndicator(Context context, AttributeSet attrs) {super(context, attrs);initView();}public void setUnderlineColor(int underlineColor) {this.underlineColor = underlineColor;}public void setUnderlineHeight(int underlineHeight) {this.underlineHeight = underlineHeight;}public void setCurrentTab(int currentTab) {setCurrentTab(currentTab, 0);}public void setCurrentTab(int currentTab, float offset) {this.currentTab = currentTab;this.offset = offset;invalidate();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() + underlineHeight);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b - underlineHeight);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int childCount = getChildCount();if (childCount <= 0 || currentTab < 0 || currentTab >= childCount) {return;}if (offset < -1) {offset = -1;}if (offset > 1) {offset = 1;}View child = getChildAt(currentTab);int underlineWidth = child.getWidth();int left = child.getLeft();int right = child.getRight();int bottom = getHeight() - getPaddingBottom();int top = bottom - underlineHeight;float offsetWidth = underlineWidth * offset;paint.setColor(underlineColor);canvas.drawRect(left + offsetWidth, top, right + offsetWidth, bottom, paint);}private void initView() {setOrientation(LinearLayout.HORIZONTAL);paint = new Paint();paint.setAntiAlias(true);}public void setAdapter(BaseAdapter adapter) {this.adapter = adapter;if (this.adapter == null) {removeAllViews();return;}this.adapter.registerDataSetObserver(new DataSetObserver() {@Overridepublic void onChanged() {fillChilds();}@Overridepublic void onInvalidated() {fillChilds();}});fillChilds();}protected void fillChilds() {removeAllViews();for (int i = 0; i < adapter.getCount(); i++) {final View child = adapter.getView(i, null, null);LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);params.gravity = Gravity.CENTER_VERTICAL;params.weight=1;addView(child, params);}}public static abstract class TextAdapter extends BaseAdapter {private final String[] titles;public TextAdapter(String[] titles) {this.titles = titles;}@Overridepublic int getCount() {if (titles == null || titles.length <= 0) {return 0;}return titles.length;}@Overridepublic Object getItem(int position) {if (titles == null || titles.length <= 0) {return null;}return titles[position];}@Overridepublic long getItemId(int position) {return position;}public abstract TextView getTextView(int position, View convertView, ViewGroup container);@Overridepublic View getView(final int position, View convertView, ViewGroup container) {TextView tv= getTextView(position, convertView, container);tv.setText(titles[position]);return tv;}}}
四、与ViewPager结合使用例子
TabIndicator tab = (TabIndicator) findViewById(R.id.tab);//设置下划线颜色tab.setUnderlineColor(Color.parseColor("#FFF44D06"));//设置下划线高度tab.setUnderlineHeight(6);//设置标签视图适配器tab.setAdapter(new TextAdapter(new String[]{"销量","价格","筛选"}) {@Overridepublic TextView getTextView(int position, View convertView, ViewGroup container) {return new TextView(getApplicationContext());}});ViewPager pager = (ViewPager) findViewById(R.id.pager);pager.setOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int arg0) {}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {//注意,此处是让下划线动态滑动的关键tab.setCurrentTab(arg0, arg1);}@Overridepublic void onPageScrollStateChanged(int arg0) {}});
五、特性总结
1、指示器继承线性布局的一切原有特性和语义,无任何负作用;
2、指示器完全在布局层实现,与标签视图无关,适配器中的视图可以是任意View;
3、代码量精简,使用方便,性能稳定。
国际惯例
————————————————————————————————————————————————————————
作者:薄荷记账 (转载请注明原作者)
简洁 稳定 优雅 无限可能!
0 0
- Android换页指示器TabIndicator
- 自定义Android页签TabIndicator
- android tab 换页动画
- Android指示器。
- Android标题栏进度指示器
- Android 自定义指示器<NBIndicatorView>
- Android自定义页面指示器
- Android ViewPager指示器 IndicatorBar
- Android自定义ViewPager指示器
- Android ViewPager指示器 IndicatorBar
- Android-自定义ViewPager指示器
- Android万能的指示器
- Android自定义ViewPager指示器
- Android 实现Viewpager指示器
- Android 页面指示器
- android 步骤指示器实现
- android ViewPager 指示器 PageIndicator
- Android 音乐指示器
- jq添加移除元素
- java 的三种移位方式的本质
- 【unity小技巧之五】unity编辑器脚本添加类目到unity Preferences中
- iOS 动画效果:Core Animation & Facebook
- 用MyEclipse10.0开发基于JAX-WS的Web Service实例
- Android换页指示器TabIndicator
- BCGPFormView嵌入左侧显示属性页,并且同窗口等比例缩放,属性页添加图表随窗口尺寸变化而变化
- js 校验
- Spring中@Transactional事务回滚实例及源码
- Lua - 10
- golang 设置代理
- 分别在Windows与Ubuntu系统下在C程序中打开选择对话框
- 微信样式库weui使用教程button(2)
- 2016.11.11 machine learning