ViewPager 的 PagerIndicator

本文介绍了一个自定义ViewPager指示器组件的实现方法,该组件能够随着ViewPager的滑动更新标题颜色和下划线的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class PagerIndicator extends LinearLayout implements OnPageChangeListener, OnClickListener {

	private List<String> mTitles;
	private int mTabCount;
	private int mTitleItemWidth;
	private int mLineColor;
	private int mSelectedTextColor;
	private int mNorTextColor;
	private int mTextSize = 17;
	private int mLineWidth;
	private Paint mLinePaint;
	private float mTranslationX;
	private ViewPager mViewPager;
	private List<TextView> mTextViewList;
	private OnViewPagerChangeListener listener;
	
	public interface OnViewPagerChangeListener{
		void onPageScrolled(int position, float positionOffset,int positionOffsetPixels);
	}
	
	public PagerIndicator(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	
	private void init() {
		mLineColor = getResources().getColor(R.color.indicator_bottom_line_color);
		mSelectedTextColor = getResources().getColor(R.color.indicator_selected_txt_color);
		mNorTextColor = getResources().getColor(R.color.indicator_un_selected_txt_color);
		
		mLineWidth = DensityConverter.dp2px(getContext(), 1);
		mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		mLinePaint.setColor(mLineColor);
		mLinePaint.setStrokeWidth(mLineWidth);
		mLinePaint.setStrokeCap(Cap.ROUND);
		
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		if(mTitles != null && mTitles.size() > 0 ){
			mTitleItemWidth = w / mTitles.size();
		}
	}
	
	@SuppressWarnings("deprecation")
	public void setViewPager(ViewPager viewPager){
		mViewPager = viewPager;
		initTitles();
		initTitleItemView();
		mViewPager.setOnPageChangeListener(this);
	}
	
	private void initTitleItemView() {
		mTextViewList = new ArrayList<TextView>();
		if(getChildCount() > 0){  
			this.removeAllViews();
		}
		for(int i = 0 ; i < mTabCount; i++){
			TextView titleTv  = new TextView(getContext());
			LinearLayout.LayoutParams params = new LayoutParams(0, android.view.ViewGroup.LayoutParams.MATCH_PARENT);
			params.weight = 1;
			titleTv.setText(mTitles.get(i));
			titleTv.setId(i);
			titleTv.setGravity(Gravity.CENTER);  
			titleTv.setTextColor(i == 0 ? mSelectedTextColor : mNorTextColor);
			titleTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSize);
			titleTv.setLayoutParams(params);
			titleTv.setOnClickListener(this);
			addView(titleTv);
			mTextViewList.add(titleTv);
		}
	}

	private void initTitles(){
		PagerAdapter adapter = mViewPager.getAdapter();
		mTabCount = adapter.getCount();
		mTitles = new ArrayList<String>();
		for(int i = 0 ; i < mTabCount ; i++){
			String title = (String) adapter.getPageTitle(i);
			mTitles.add(title);
		}
	}

	@Override
	public void onPageScrollStateChanged(int position) {
	}

	@Override
	public void onPageScrolled(int position, float positionOffset,int positionOffsetPixels) {
		if(null != listener){
			listener.onPageScrolled(position, positionOffset, positionOffsetPixels);
		}
		mTranslationX = getWidth() / mTabCount * (position + positionOffset);
		for(int i = 0 ; i < mTextViewList.size() ; i++){
			TextView textView = mTextViewList.get(i);
			if(position == i){
				textView.setTextColor(mSelectedTextColor);
			}else{
				textView.setTextColor(mNorTextColor);
			}
		}
		invalidate();
	}

	@Override
	public void onPageSelected(int state) {}
	
	//绘制下划线
	@Override
	protected void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
		canvas.save();
		canvas.translate(mTranslationX, getHeight() - mLineWidth / 2);
		canvas.drawLine(0, 0, mTitleItemWidth, 0, mLinePaint);
		canvas.restore();
	}

	@Override
	public void onClick(View v) {
		int id = v.getId();
		mViewPager.setCurrentItem(id);
	}

	public void setOnViewPagerChangeListener(OnViewPagerChangeListener l) {
		this.listener = l;
	}
}

核心代码:

计算需要移动的距离

mTranslationX = getWidth() / mTabCount * (position + positionOffset);
for(int i = 0 ; i < mTextViewList.size() ; i++){
	TextView textView = mTextViewList.get(i);
	if(position == i){
		textView.setTextColor(mSelectedTextColor);
	}else{
		textView.setTextColor(mNorTextColor);
	}
}
invalidate();

绘制背景

@Override
protected void dispatchDraw(Canvas canvas) {
	super.dispatchDraw(canvas);
	canvas.save();
	canvas.translate(mTranslationX, getHeight() - mLineWidth / 2);
	canvas.drawLine(0, 0, mTitleItemWidth, 0, mLinePaint);
	canvas.restore();
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值