美文网首页
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

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