通过自定义View,创建一个圆形指示器
16lz
2021-01-26
在项目中只要涉及到滑动的地方,很多时候都需要用到指示器。那么今天就通过自定义View来创建一个属于自己的指示器。
效果图:
首先,在res - values下新建一个attr文件, 可命名为:attr_indicator.xml 代码如下:
<resources> <declare-styleable name="PageIndicatorView"> <attr name="circleInterval" format="dimension"/> <attr name="circleSizi" format="dimension"/> <attr name="circleNumber" format="integer"/> <attr name="selectIndex" format="integer"/> <attr name="circleSelectColor" format="color"/> <attr name="circleUnSelectColor" format="color"/> declare-styleable>resources>
然后。新建一个类,继承View,这里命名为:PageIndicatorView
代码如下:
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;import com.yikelive.R;import androidx.annotation.Nullable;public class PageIndicatorView extends View { private Paint mPaint; private int mCircleInterval;//设置圆和点圆之间的间隔 private int mCircleRadius;//设置圆的大小 private int mCircleNumber;//设置圆的个数 private int mSelectIndex = 1;//设置选中的圆 private int mScreenWidht; private int mScreenHeight; private int mWidht; private int mHeight; private int mSelectColor; private int mUnSelectColor; public void setmCircleNumber(int mCircleNumber) { this.mCircleNumber = mCircleNumber; } public void setIndex(int selectIndex) { if (selectIndex > mCircleNumber) { this.mSelectIndex = mCircleNumber; } else { this.mSelectIndex = selectIndex; } postInvalidate(); } public void setmSelectColor(int mSelectColor) { this.mSelectColor = mSelectColor; } public void setmUnSelectColor(int mUnSelectColor) { this.mUnSelectColor = mUnSelectColor; } public PageIndicatorView(Context context) { this(context, null); } public PageIndicatorView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public PageIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(Color.BLACK); mPaint.setStrokeWidth(20); mPaint.setStyle(Paint.Style.FILL); mScreenWidht = context.getResources().getDisplayMetrics().widthPixels; mScreenHeight = context.getResources().getDisplayMetrics().heightPixels; TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PageIndicatorView, defStyleAttr, 0); int count = ta.getIndexCount(); for (int i = 0; i < count; i++) { int index = ta.getIndex(i); switch (index) { case R.styleable.PageIndicatorView_circleInterval: mCircleInterval = ta.getDimensionPixelSize(index, (int) TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_PX, 12, context.getResources().getDisplayMetrics())); break; case R.styleable.PageIndicatorView_circleNumber: mCircleNumber = ta.getInt(index, 4); break; case R.styleable.PageIndicatorView_circleSizi: mCircleRadius = ta.getDimensionPixelOffset(index, (int) TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_DIP, 12, context.getResources().getDisplayMetrics())); break; case R.styleable.PageIndicatorView_selectIndex: mSelectIndex = ta.getInt(index, 1); break; case R.styleable.PageIndicatorView_circleSelectColor: mSelectColor = ta.getColor(index, Color.WHITE); break; case R.styleable.PageIndicatorView_circleUnSelectColor: mUnSelectColor = ta.getColor(index, Color.BLACK); break; } } ta.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int wMode = MeasureSpec.getMode(widthMeasureSpec); int wSize = MeasureSpec.getSize(widthMeasureSpec); int hMode = MeasureSpec.getMode(heightMeasureSpec); int hSize = MeasureSpec.getSize(heightMeasureSpec); int viewWidht = 0; int viewHeight = 0; switch (wMode) { case MeasureSpec.EXACTLY: viewWidht = wSize; break; case MeasureSpec.AT_MOST: viewWidht = mCircleInterval + getPaddingLeft() + getPaddingRight() + mCircleRadius * 2; break; case MeasureSpec.UNSPECIFIED: viewWidht = wSize; break; } switch (hMode) { case MeasureSpec.EXACTLY: viewHeight = wSize; break; case View.MeasureSpec.AT_MOST: viewHeight = getPaddingBottom() + getPaddingTop() + mCircleRadius * 2; break; case MeasureSpec.UNSPECIFIED: viewHeight = wSize; break; } setMeasuredDimension(resolveSize(viewWidht, widthMeasureSpec), resolveSize(viewHeight, heightMeasureSpec)); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidht = w; mHeight = h; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int mViewWidht; for (int i = 1; i <= mCircleNumber; i++) { if (mSelectIndex == i) { mPaint.setColor(mSelectColor); canvas.drawCircle((2 * i - 1) * mCircleRadius + mCircleInterval * (i - 1), mCircleRadius, mCircleRadius, mPaint); continue; } mPaint.setColor(mUnSelectColor); canvas.drawCircle((2 * i - 1) * mCircleRadius + mCircleInterval * (i - 1), mCircleRadius, mCircleRadius, mPaint); } }}
下面就是在xml布局文件文件中的应用:
<com.yikelive.ui.vip.newVip.assets.PageIndicatorView android:id="@+id/pv_point" android:layout_width="wrap_content" android:layout_height="wrap_content" app:circleInterval="3dp" app:circleSelectColor="#fbe29c" app:circleSizi="3dp" app:circleUnSelectColor="#666"/>
最后说一下在控制器中的使用,初始化一下指示器数量和默认选中位置,然后即是改变逻辑,以ViewPager为例,在ViewPager的翻页完成监听 ( onPageSelected() )中执行 指示器的**setIndex(position + 1)**方法即可。
代码如下:
// 设置指示器数量 host.pv_point.setmCircleNumber(users.size) //设置指示器初始选中位置(从1开始) host.pv_point.setIndex(1) // ViewPager监听 host.rv_head.setOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageScrollStateChanged(state: Int) { } override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { }//翻页完成后执行 override fun onPageSelected(position: Int) { //指示器选中位置改变 host.pv_point.setIndex(position + 1) } })
到此。一个指示器就全部完成了。
更多相关文章
- 【UI交互效果】android UI效果二: 给选中的图片加边框
- APP字体大小,不随系统的字体大小变化而变化的方法
- Android(安卓)ViewGroup.setDescendantFocusability函数
- Android(安卓)ListView中 每一项都有不同的布局
- android百度地图开发总结
- Android使用Canvas绘制圆形进度条效果
- Android(安卓)Jetpack Compose 最全上手指南 | 开发者说·DTalk
- Android、java环境搭建流程
- unity3d深入学习笔记6:发布Android(安卓)apk