美文网首页
An_zdyview_circle

An_zdyview_circle

作者: android_en | 来源:发表于2017-10-26 11:13 被阅读8次

实现自定义控件小圆环效果;
First:我们定义一个attrs.xml 在values包里

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyProgressRound">
        <attr name="progressColor" format="color"/>
        <attr name="textSize" format="dimension"/>
        <attr name="ringSize" format="dimension"/>
        <attr name="radiuSize" format="dimension"/>
    </declare-styleable>

</resources>

Second:建立实类MyProgressRound继承view:

package com.example.weekone;

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.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * Created by dd 
 * 在xml里面可以设置 进度圆环的属性
 * 1、颜色
 * 2、文本大小
 * 3、粗细
 * 4、圆环半径
 *
 * ***** values文件夹里面  创建一个attrs.xml
 * ***** 命名控件 namesp ?
 * <>
 *     <attr name="layout_width" format=""><attr/>
 * </>
 */

public class MyProgressRound extends View{

    Paint paint;

    private int mProgress = 0;
    private int mCountProgress = 0;

    private float mRadiuSize = 0;
    private float mRingSize = 0;
    private float mTextSize = 0;
    private int mProgressColor = 0;


    public MyProgressRound(Context context) {
        super(context);
        init();
    }

    /**
     * 所有在xml布局文件中 标签里面声明的属性 都可以在AttributeSet类的对象中获取出来
     * @param context
     * @param attrs
     */
    public MyProgressRound(Context context, @Nullable AttributeSet attrs) {
        //在该构造方法中可以获取到  所有参数
        //把参数传出去  在onDraw方法中可以操作  onMeasure中也可以操作
        super(context, attrs);
        getCustomAttr(context, attrs);
        init();
    }

    private void getCustomAttr(Context context, AttributeSet attrs) {
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyProgressRound);
        mRadiuSize = array.getDimension(R.styleable.MyProgressRound_radiuSize, 100);
        mRingSize = array.getDimension(R.styleable.MyProgressRound_ringSize, 10);
        mTextSize = array.getDimension(R.styleable.MyProgressRound_textSize, 10);
        mProgressColor = array.getColor(R.styleable.MyProgressRound_progressColor, Color.BLACK);

    }


    public MyProgressRound(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void init(){
        paint = new Paint();
        paint.setAntiAlias(true);
    }

    //widthMeasureSpec/heightMeasureSpec 是一个32为的int类型
    //01000000 00000000 00000000 00000000
    //高两位 代表类型
    //warpcontent类型 MeasureSpec.AT_MOST
    //matchparent类型 MeasureSpec.EXACTLY 或者具体的长度 100dp 200dp
    // 其他类型
    //
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int width = 0;
        int height = 0;
        if(widthMode == MeasureSpec.AT_MOST){
            width = (int) (mRadiuSize * 2);
        }else{
            width = Math.max(widthSize, (int) (mRadiuSize * 2));
        }

        if(heightMode == MeasureSpec.AT_MOST){
            height = (int) (mRadiuSize * 2);
        }else{
            height = Math.max(heightSize, (int) (mRadiuSize * 2));
        }

        setMeasuredDimension(width, height);

//        switch (widthMode){
//            case MeasureSpec.AT_MOST:
//                //如果宽度使用的是warp_content那么 我们需要手动设置控件的宽值, 标准是宽是半径的2倍
//                Log.i("=============widthMode", "onMeasure: " + "AT_MOST---> warp_content");
//                //确定了宽高后,修改控件的宽高
//                setMeasuredDimension((int)(mRadiuSize * 2), (int)(mRadiuSize * 2));
//                break;
//            case MeasureSpec.EXACTLY:
//                Log.i("=============widthMode", "onMeasure: " + "Exactly---> match_parent");
//                break;
//        }
//
//        switch (heightMode){
//            case MeasureSpec.AT_MOST:
//                Log.i("=============heightMode", "onMeasure: " + "AT_MOST---> warp_content");
//                break;
//            case MeasureSpec.EXACTLY:
//                Log.i("=============heightMode", "onMeasure: " + "Exactly---> match_parent");
//                break;
//        }



    }



    @Override
    protected void onDraw(Canvas canvas) {
        //在布局文件中设置的圆环半径大小就可以不用写死
        paint.setStrokeWidth(0);
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(getMeasuredWidth()/2, getMeasuredHeight()/2, mRadiuSize, paint);
        canvas.drawCircle(getMeasuredWidth()/2, getMeasuredHeight()/2, mRadiuSize - mRingSize, paint);

        paint.setTextSize(mTextSize);
        String text = mCountProgress + "%";
        float textWidth = paint.measureText(text);
        canvas.drawText(text, getMeasuredWidth()/2-textWidth/2 , getMeasuredWidth()/2 + mTextSize/2, paint);

        RectF rectF = new RectF(getMeasuredWidth()/2 - mRadiuSize + mRingSize/2,getMeasuredHeight()/2 - mRadiuSize + mRingSize/2,getMeasuredWidth()/2 + mRadiuSize - mRingSize/2,getMeasuredHeight()/2 + mRadiuSize - mRingSize/2);
        paint.setStrokeWidth(mRingSize);
        paint.setColor(mProgressColor);
        canvas.drawArc(rectF, 0, mProgress, false, paint);
    }

    public void setProgress(int progress){
        mProgress = progress;
        mCountProgress = progress * 100 / 360;
        invalidate();
    }
}

Threed: 在布局文件里初始化控件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.weekone.MainActivity">

    <com.example.weekone.MyProgressRound
        android:id="@+id/mpr"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#f00"
        app:ringSize="10dp"
        app:progressColor="#883399"
        app:radiuSize="100dp"
        app:textSize="20sp"
        android:layout_centerInParent="true"
        />

</RelativeLayout>

Last:我们在MainActivity里面实现具体的操作:

package com.example.weekone;

import android.os.AsyncTask;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    MyProgressRound mpr;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mpr = (MyProgressRound) findViewById(R.id.mpr);

        new AsyncTask<String, Integer, String>(){

            @Override
            protected String doInBackground(String... params) {
                for (int i = 0; i <= 360; i++) {
                    SystemClock.sleep(10);
                    publishProgress(i);
                }

                return null;
            }

            //该方法的调用条件是   publishProgress
            @Override
            protected void onProgressUpdate(Integer... values) {
                mpr.setProgress(values[0]);
            }
        }.execute();

    }
}

相关文章

  • An_zdyview_circle

    实现自定义控件小圆环效果;First:我们定义一个attrs.xml 在values包里 Second:建立实类M...

网友评论

      本文标题:An_zdyview_circle

      本文链接:https://www.haomeiwen.com/subject/mcwhpxtx.html