1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Android 自定义控件 ViewPager头部指示器控件 ViewPagerBelowIndicator

Android 自定义控件 ViewPager头部指示器控件 ViewPagerBelowIndicator

时间:2023-05-02 10:59:32

相关推荐

Android 自定义控件 ViewPager头部指示器控件 ViewPagerBelowIndicator

效果

演示

说明

为了实现 ViewPager 切换 Fragment 时的标签效果(类似新闻客户端导航的效果)

代码

package com.demo.view;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.Path;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.Gravity;import android.view.View;import android.view.WindowManager;import android.widget.LinearLayout;import android.widget.TextView;import com.demo.R;import com.demo.factory.Axis;import java.util.List;public class ViewPagerBelowIndicator extends LinearLayout {/*** view的宽度*/private int mWidth=-1;public void setmWidth(int mWidth) {this.mWidth = mWidth;}/*** 默认字体大小*/private final float DEFAULT_TEXTSIZE=Axis.scaleTextSize(30);private float textSize=-1f;//字体大小public void setTextSize(float textSize) {this.textSize = textSize;}/*** 指示器文字位置*/private int IndicatePosition = 1;/*** 绘制矩形的画笔*/private Paint mPaint;/*** path构成一个矩形*/private Path mPath;/*** 矩形的宽度*/private int mTriangleWidth;/*** 画笔颜色*/private int IndicatorColor = 0xFFFFFFFF;/*** 矩形的高度*/private int mTriangleHeight = 50; //指示条的高度private int mTriangleH;private static final float MAGNIFICATION_DEFAULT_TAB = (float) 3.0;/*** 矩形的宽度为单个Tab的1/3*/private static final double RADIO_TRIANGEL = 1.0f / 3;/*** 矩形的最大宽度*/private int dimension_triangel_width = (int) (getScreenWidth() / 3 * RADIO_TRIANGEL);/*** 初始时,矩形指示器的偏移量*/private int mInitTranslationX;/*** 手指滑动时的偏移量*/private float mTranslationX;/*** 默认的Tab数量*/private final int COUNT_DEFAULT_TAB = 3;/*** tab数量*/private int mTabVisibleCount = COUNT_DEFAULT_TAB;/*** tab上的内容*/private List<String> mTabTitles;/*** 与之绑定的ViewPager*/public ViewPager mViewPager;/*** 标题正常时的颜色*/private int COLOR_TEXT_NORMAL = 0xFF999999;/*** 标题选中时的颜色*/private int COLOR_TEXT_HIGHLIGHTCOLOR = 0xFFFFFFFF;public ViewPagerBelowIndicator(Context context) {this(context, null);}public ViewPagerBelowIndicator(Context context, AttributeSet attrs) {super(context, attrs);// 获得自定义属性,tab的数量TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator);mTabVisibleCount = 6;//设置指示条宽度的放大系数float magnification = 1.0f / 4;dimension_triangel_width = (int) (getScreenWidth() / 3 * magnification);if (mTabVisibleCount < 0)mTabVisibleCount = COUNT_DEFAULT_TAB;a.recycle();// 初始化画笔mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setColor(IndicatorColor);mPaint.setStyle(Style.FILL);//mPaint.setPathEffect(new CornerPathEffect(4));}/*** 绘制指示器*/@Overrideprotected void dispatchDraw(Canvas canvas) {canvas.drawColor(0x00FFFFFF);canvas.save();// 画笔平移到正确的位置canvas.translate(mInitTranslationX + mTranslationX, getHeight());canvas.drawPath(mPath, mPaint);canvas.restore();super.dispatchDraw(canvas);}/*** 初始化矩形的宽度*/@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);mTriangleH = (int) (w / mTabVisibleCount * RADIO_TRIANGEL);// widthmTriangleWidth = Math.min(dimension_triangel_width, dimension_triangel_width);//初始化矩形指示器iniTrectangle();// 初始时的偏移量mInitTranslationX = getWidth() / mTabVisibleCount / 2 - mTriangleWidth/ 2;}/*** 设置可见的tab的数量** @param count*/public void setVisibleTabCount(int count) {this.mTabVisibleCount = count;}public void setIndicatePosition(int IndicatePosition){this.IndicatePosition = getHeight();invalidate();}/*** 设置tab的标题内容 可选,可以自己在布局文件中写死** @param datas*/public void setTabItemTitles(List<String> datas) {// 如果传入的list有值,则移除布局文件中设置的viewif (datas != null && datas.size() > 0) {this.removeAllViews();this.mTabTitles = datas;for (String title : mTabTitles) {// 添加viewaddView(generateTextView(title));}// 设置item的click事件setItemClickEvent();}}/*** 对外的ViewPager的回调接口*/public interface PageChangeListener {public void onPageScrolled(int position, float positionOffset,int positionOffsetPixels);public void onPageSelected(int position);public void onPageScrollStateChanged(int state);}// 对外的ViewPager的回调接口private PageChangeListener onPageChangeListener;// 对外的ViewPager的回调接口的设置public void setOnPageChangeListener(PageChangeListener pageChangeListener) {this.onPageChangeListener = pageChangeListener;}// 设置关联的ViewPagerpublic void setViewPager(ViewPager mViewPager, int pos) {this.mViewPager = mViewPager;mViewPager.addOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int position) {// 设置字体颜色高亮resetTextViewColor();highLightTextView(position);// 回调if (onPageChangeListener != null) {onPageChangeListener.onPageSelected(position);}}@Overridepublic void onPageScrolled(int position, float positionOffset,int positionOffsetPixels) {// 滚动scroll(position, positionOffset);// 回调if (onPageChangeListener != null) {onPageChangeListener.onPageScrolled(position,positionOffset, positionOffsetPixels);}}@Overridepublic void onPageScrollStateChanged(int state) {// 回调if (onPageChangeListener != null) {onPageChangeListener.onPageScrollStateChanged(state);}}});// 设置当前页mViewPager.setCurrentItem(pos);// 高亮highLightTextView(pos);}/*** 设置指示器颜色*/public void setIndicatorColor(int IndicatorColor){this.IndicatorColor = IndicatorColor;mPaint.setColor(IndicatorColor);invalidate();}/*** 设置正常标题颜色* @param COLOR_TEXT_NORMAL*/public void setCOLOR_TEXT_NORMAL(int COLOR_TEXT_NORMAL) {this.COLOR_TEXT_NORMAL = COLOR_TEXT_NORMAL;}/*** 设置选中标题颜色* @param COLOR_TEXT_HIGHLIGHTCOLOR*/public void setCOLOR_TEXT_HIGHLIGHTCOLOR(int COLOR_TEXT_HIGHLIGHTCOLOR) {this.COLOR_TEXT_HIGHLIGHTCOLOR = COLOR_TEXT_HIGHLIGHTCOLOR;}/*** 高亮文本** @param position*/protected void highLightTextView(int position) {View view = getChildAt(position);if (view instanceof TextView) {((TextView) view).setTextColor(COLOR_TEXT_HIGHLIGHTCOLOR);}}/*** 重置文本颜色*/private void resetTextViewColor() {for (int i = 0; i < getChildCount(); i++) {View view = getChildAt(i);if (view instanceof TextView) {((TextView) view).setTextColor(COLOR_TEXT_NORMAL);}}}/*** 设置点击事件*/public void setItemClickEvent() {int cCount = getChildCount();for (int i = 0; i < cCount; i++) {final int j = i;View view = getChildAt(i);view.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {mViewPager.setCurrentItem(j);}});}}/*** 根据标题生成我们的TextView** @param text* @return*/private TextView generateTextView(String text){TextView tv = new TextView(getContext());LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);lp.width =(mWidth!=-1?mWidth:getScreenWidth())/ mTabVisibleCount;tv.setGravity(Gravity.CENTER);tv.setTextColor(COLOR_TEXT_NORMAL);tv.setText(text);tv.setTextSize(textSize!=-1f?textSize:DEFAULT_TEXTSIZE);tv.setLayoutParams(lp);return tv;}/*** 初始化矩形指示器*/private void iniTrectangle() {mPath = new Path();mPath.rewind();mTriangleHeight = 50;//指示条的高度mPath.moveTo(mTriangleWidth, mTriangleHeight / 5);mPath.lineTo(-mTriangleWidth / 100, mTriangleHeight / 5);mPath.lineTo(-mTriangleWidth / 100, -mTriangleHeight / 5);mPath.lineTo(mTriangleWidth, -mTriangleHeight / 5);mPath.close();}/*** 指示器跟随手指滚动,以及容器滚动** @param position* @param offset*/public void scroll(int position, float offset) {/*** <pre>* 0-1:position=0 ;1-0:postion=0;* </pre>*/// 不断改变偏移量,invalidatemTranslationX = getWidth() / mTabVisibleCount * (position + offset);int tabWidth = getScreenWidth() / mTabVisibleCount;// 容器滚动,当移动到倒数最后一个的时候,开始滚动if (offset > 0 && position >= (mTabVisibleCount - 2)&& getChildCount() > mTabVisibleCount) {if (mTabVisibleCount != 1) {this.scrollTo((position - (mTabVisibleCount - 2)) * tabWidth+ (int) (tabWidth * offset), 0);} else// 为count为1时 的特殊处理{this.scrollTo(position * tabWidth + (int) (tabWidth * offset), 0);}}invalidate();}/*** 设置布局中view的一些必要属性;如果设置了setTabTitles,布局中view则无效*/@Overrideprotected void onFinishInflate() {super.onFinishInflate();int cCount = getChildCount();if (cCount == 0)return;for (int i = 0; i < cCount; i++) {View view = getChildAt(i);LayoutParams lp = (LayoutParams) view.getLayoutParams();lp.weight = 0;lp.width = getScreenWidth() / mTabVisibleCount;view.setLayoutParams(lp);}// 设置点击事件setItemClickEvent();}/*** 获得屏幕的宽度** @return*/public int getScreenWidth() {WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);return outMetrics.widthPixels;}}

使用方式

1 . Activity中初始化设置

indicator=new ViewPagerBelowIndicator(this);int mWidth= Axis.getWidth()-Axis.scaleX(300)*2;indicator.setmWidth(mWidth);indicator.setVisibleTabCount(3);indicator.setCOLOR_TEXT_NORMAL(Color.BLACK);indicator.setTextSize(Axis.scaleTextSize(32));indicator.setCOLOR_TEXT_HIGHLIGHTCOLOR(ContextCompat.getColor(this,R.color.color3973FF));indicator.setIndicatorColor(Color.TRANSPARENT);RelativeLayout.LayoutParams indicator_lp=new RelativeLayout.LayoutParams(mWidth,HEAD_WIDTH);indicator_lp.addRule(RelativeLayout.CENTER_IN_PARENT);headView.addView(indicator,indicator_lp);

2 . 和 ViewPager 对象关联

List<String> mTitles = Arrays.asList("云端", "车机", "手机");//给tab加上标题indicator.setTabItemTitles(mTitles);//设置关联的ViewPager,默认显示第一个indicator.setViewPager(mViewPager,1);//mViewPager为ViewPager子类

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