Android自定义组件学习笔记(1)---仿网页进度条

    xiaoxiao2021-12-03  18

    最近公司的工作比较清闲,所以想要学习一些东西,就选择了自己一直想要学习的自定义组件。其实学习自定义组件也不是第一次了,只不过每次学习在之后的项目中却一直用不到,导致自己进入了一个学会一点过两天忘一点的尴尬境地。这次下定决心,边学习边笔记。

    参考资料

    http://blog.csdn.net/aigestudio/article/details/41212583/ 学习的时候一直看的 AigeStudio的文章,感觉很详细

    开始实战

    首先写一个简单的小demo,正好有一个简单的等待条需要实现,上效果 好了现在说说实现思路 1、首相分析一下动画,显示一个弧线画圆的过程,然后是圆减少变成空白,再画圆的过程,代码实现应该画弧线,改变弧线的角度 2、还有就是需要弧线起点的一个变化 开始实现 import android.content.Context; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; /** * Created by qiaoda on 2016/11/18. */ public class CircleProgress extends View { /** *重写构造方法,最终都走 CircleProgress(Context context, AttributeSet attrs, int defStyleAttr)构造方法 * @param context */ public CircleProgress(Context context) { this(context,null); } public CircleProgress(Context context, AttributeSet attrs) { this(context, attrs,0); } public CircleProgress(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } }现在一个自定义组件已经可以说是完成了,当然你能看到的只是一片空白,之后就应该用画笔来实现一个能看见的效果了。 首先在构造方法中初始化画笔 public CircleProgress(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initPaint(); } /** *画笔 */ private Paint mPaint; /** * 初始化画笔 */ private void initPaint(){ mPaint = new Paint(); mPaint.setColor(Color.GREEN);//设置画笔颜色 mPaint.setStrokeWidth(5); //设置画笔宽度 mPaint.setAntiAlias(true); // 消除锯齿 mPaint.setStyle(Paint.Style.STROKE); // 我们这里实现画线所以设置空心 }好的,画笔初始化完成,下面我们开始画画。开始绘制的我们需要在onDraw(Canvas canvas)方法中来实现,前边我们初始化了画笔,相应的我们还得有画布,Canvas 就是我们的画布,下面我们用canvas.drawArc()方法来实现圆弧。 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int centre = getWidth() / 2; // 获取圆心的x坐标 int radius = centre - 5 / 2;// 半径 RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限 canvas.drawArc(oval, -90, 360, false, mPaint); // 根据进度画圆弧 }好了现在我们已经在界面上看机了一个绿色的小圆,总算是有东西了对不对。下面来说一下实现思路,弧线其实和圆的画法比较相似,它本身就可以看成是圆的一部分,所以肯定需要一个圆心和半径,圆心当然要选组件的中心点,在这里说明我写的这个组件宽高需要自己设定,而且最好宽高一致,半径就为宽度的一半减去画笔的宽度,不然就会有部分出去了。 下面我来说明一下 drawArc的具体参数 RectF             oval                  表示绘制的区域 flast                startAngle        表示绘制的角度,0度为最右边的点,一圈分为360度逆时针为负数,顺时针为正数 flast                sweepAngle   表示弧线经过的角度,我这里为360度也就是一圈 boolean        useCenter       表示是否与中点连线 Paint              paint                这个不用说了  就是画笔   好了下面就让它转动起来 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int centre = getWidth() / 2; // 获取圆心的x坐标 int radius = centre - 5 / 2;// 半径 setProgress(); RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限 if (isPositive) { canvas.drawArc(oval, startOval, mProgress, false, mPaint); // 根据进度画圆弧 } else { canvas.drawArc(oval, startOval, -mProgress, false, mPaint); // 根据进度画圆弧 } postInvalidateDelayed(5);//每隔5毫秒刷新一次 } /** * 判断绘制方向方向 */ private boolean isPositive = true; /** * 绘制点位置 */ private int startOval = -90; /** * 绘制弧线的角度 */ private int mProgress = 0; /** * 计算圆环显示进度和起点 */ private void setProgress() { if (mProgress == 360) { isPositive = false; } else if (mProgress == 0) { isPositive = true; } if (isPositive) { mProgress = mProgress + 4; } else { mProgress = mProgress - 4; } startOval += 3; } 现在已经转起来了,来看看效果 下面具体说一下我的视线步骤,首先我要是实现圆弧的增长和缩减,我在当它角度为360的时候知道已经画完一个圆,开始缩减的过程用isPositive判断,当它缩减的过程中应为逆时针收缩,所以在mProgress前加一个-号。然后有个一值控制绘制点的位置,startOval为绘制点,它也是不断变化的。下面给出完整代码 import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; /** * 自定义的圆形等待条 * Created by qiaoda on 2016/11/17. */ public class UUCircleProgress extends View { /** * 第一圈的颜色 */ private int mCircleColor; /** * 圈的宽度 */ private int mCircleWidth; /** * 画笔 */ private Paint mPaint; /** * 当前进度 */ private int mProgress = 0; /** * 速度 */ private int mSpeed = 10; /** * 进度开始点 */ private int startOval = -90; /** * 判断方向 */ private boolean isPositive = true; /** * 判断是否开始 */ private boolean isStart = true; public UUCircleProgress(Context context) { this(context, null); } public UUCircleProgress(Context context, AttributeSet attrs) { this(context, attrs, 0); } public UUCircleProgress(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.UUCircleProgress, defStyle, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.UUCircleProgress_circlecolor: mCircleColor = a.getColor(attr, Color.GREEN); break; case R.styleable.UUCircleProgress_circleWidth: mCircleWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics())); break; } } a.recycle(); initPaint(); } /** * 初始化画笔 */ private void initPaint() { mPaint = new Paint(); mPaint.setStrokeWidth(mCircleWidth); // 设置圆环的宽度 mPaint.setAntiAlias(true); // 消除锯齿 mPaint.setStyle(Paint.Style.STROKE); // 设置空心 mPaint.setColor(mCircleColor); // 设置圆环的颜色 } @Override protected void onDraw(Canvas canvas) { int centre = getWidth() / 2; // 获取圆心的x坐标 int radius = centre - mCircleWidth / 2;// 半径 RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限 setProgress(); if (isPositive) { canvas.drawArc(oval, startOval, mProgress, false, mPaint); // 根据进度画圆弧 } else { canvas.drawArc(oval, startOval, -mProgress, false, mPaint); // 根据进度画圆弧 } if (isStart) { //根据时间间隔刷新 postInvalidateDelayed(mSpeed); } } /** * 计算圆环显示进度和起点 */ private void setProgress() { if(isStart){ if (mProgress == 360) { isPositive = false; } else if (mProgress == 0) { isPositive = true; } if (isPositive) { mProgress = mProgress + 4; } else { mProgress = mProgress - 4; } startOval += 3; } } /** * 重新启动动画 */ public void start() { isStart = true; postInvalidate(); } /** * 动画停止 */ public void stop() { isStart = false; } /** * 判断是否显示动画 * @return */ public boolean isStart(){ mProgress = 0; startOval = -90; isPositive = true; return isStart; } } <declare-styleable name="UUCircleProgress"> <attr name="circlecolor" /> <attr name="circleWidth" /> </declare-styleable> <路径.UUCircleProgress android:layout_width="50dp" android:layout_height="50dp" app:circlecolor="@color/whole_blue" android:layout_gravity="center" app:circleWidth="5dp"/>
    转载请注明原文地址: https://ju.6miu.com/read-680163.html

    最新回复(0)