Android 自定义View---进度条

发布时间:2019-06-29 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Android 自定义View---进度条脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

简介

AndROId系统内置的控件有时候无法满足我们的效果,这时候可以自定义View。自定义View可以通过几种方式实现:

  1. 继承View重写OnDraw方法
  2. 继承ViewGrouP实现特殊的Layout
  3. 继承特定的View(比如TextView)
  4. 继承特定的ViewGroup(比如LinearLayout)

本文实现一个通过继承View实现自定义的加载进度条,效果如下图所示:

Android 自定义View---进度条


(gif录的有点卡,真机上不会)

自定义属性

首先新建一个名为ColorPRogressBar的class继承View。为了提供一些可定制属性,在values目录下新建一个attrs.XMl文件,内容如下:

<?xML version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ColorProgressBar">
        <attr name="FirstColor" format="color" />
        <attr name="secondColor" format="color" />
        <attr name="circleWidth" format="dimension" />
    </declare-styleable>
</resources>

其中提供了进度条的两种颜色以及度几种属性。然后在布局文件中,使用这些属性。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout >"http://schemas.android.COM/apk/res/android"
    >"http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.example.administrator.test.ColorPregressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="100dp" />

    <com.example.administrator.test.ColorPregressBar
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_gravity="center"
        android:layout_marginTop="80dp"
        app:circleWidth="16dp"
        app:firstColor="#f58a47"
        app:secondColor="#5be9d8"
        />
</LinearLayout>

上面在布局文件中使用了两个自定义的控件,第二个定制了颜色、宽度。

@H_304_206@获取属性

ColorProgressBar的构造方法中获取布局文件中的属性,如下所示:

public class @H_406_227@ColorPregressBar extends View {
    private Paint mPaint;
    private RectF mRectF;
    //进度
    private int mProgress;

    //颜色以及宽度
    private int mFirstColor;
    private int mSecondColor;
    private int mCircleWidth;
    
    //是否到下一圈
    private boolean mChanged;
    
    //空间的宽度 以及 高度(两个值设为一样)
    private int mWidth;

    public ColorPregressBar(Context context) {
        this(context, null);
    }

    public ColorPregressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ColorPregressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray ta = context.oBTainStyledAttributes(attrs, R.styleable.ColorProgressBar);
        mFirstColor = ta.getColor(R.styleable.ColorProgressBar_firstColor, Color.red);
        mSecondColor = ta.getColor(R.styleable.ColorProgressBar_secondColor, Color.BLUE);
        mCircleWidth = ta.getDimensionPixelSize(R.styleable.ColorProgressBar_circleWidth, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 6, getResources().getDisplayMetrics()));
        ta.recycle();

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.stroke);
        mPaint.setStrokeWidth(mCircleWidth);

        mChanged = false;
    }
    ...//省略了其他方法
}

onMeasure

如果布局文件中控件的宽度设为wrap_content,必须要进行特殊处理,代码如下:

@override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);

    if (widthMode == MeasureSpec.AT_MOST) {
        mWidth = Math.min(widthSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 160, getResources().getDisplayMetrics()));
        setMeasuredDimension(mWidth, mWidth);
    }
}

onMeasure中,如果MeasurecSpec的模式是AT_MOST则把宽高设置为160像素。

onDraw

最关键的代码在于onDraw方法,这里实现了圆的绘制以及更新:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    int center = getWidth() / 2;
    int radius = center - mCircleWidth / 2;
    mRectF = new RectF(center - radius, center - radius, center + radius, center + radius);
    if (!mChanged) {
        mPaint.setColor(mSecondColor);
        canvas.drawCircle(center, center, radius, mPaint);
        mPaint.setColor(mFirstColor);
        canvas.drawArc(mRectF, -90, mProgress, false, mPaint);
    } else {
        mPaint.setColor(mFirstColor);
        canvas.drawCircle(center, center, radius, mPaint);
        mPaint.setColor(mSecondColor);
        canvas.drawArc(mRectF, -90, mProgress, false, mPaint);
    }
    startProgress();
}

上面的实现方法是先判断当前颜色,画一个圆形,然后改成另一种颜色绘制一段圆弧,代表进度。进度的更新是调用startProgress方法,代码如下:

private void startProgress() {
    if (isShown()) {
        postDelayed(new Runnable() {
            @Override
            public void run() {
                LOG.d("ly", "调用post");
                mProgress += 10;
                if (mProgress >= 360) {
                    mProgress = 0;
                    mChanged = !mChanged;
                }
                invalidate();
            }
        }, 10);
    }
}

其实就是在控件显示的情况下增加mProgress的值,如果进度到头了则重新变为0开始下一圈,然后调用invalidate更新视图。每10毫秒更新一次,不断循环。这个也可以用线程实现,不过要在onDetachedFromWindow方法中关闭线程,以免内存泄漏

脚本宝典总结

以上是脚本宝典为你收集整理的Android 自定义View---进度条全部内容,希望文章能够帮你解决Android 自定义View---进度条所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。