自定义View画圆 跟踪进度条 及改变颜色

来源:互联网 发布:网络推广职责 编辑:程序博客网 时间:2024/06/18 13:47

1、自定义View的属性

2、在View的构造方法中获得我们自定义的属性

[ 3、重写onMesure ]

4、重写onDraw

我把3用[]标出了,所以说3不一定是必须的,当然了大部分情况下还是需要重写的。

1、自定义View的属性,首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="MyView">        <attr name="radius" format="dimension"/>        <attr name="stripeWidth" format="dimension"/>   <!--色带宽度-->        <attr name="percent" format="integer"/>         <!--百分比 最大值为100-->        <attr name="smallColor" format="color"/>        <!--色带宽度-->        <!--外圈颜色-->        <attr name="bigColor" format="color"/>        <!--中间字体颜色-->        <attr name="centerTextSize" format="dimension"/>        <!--色带宽度-->    </declare-styleable></resources>

创建一个 Myview类来继承View 来实现它的及格有参构造

public class MyView extends View {    //圆的半径    private float mRadius;    //色带的宽度    private float mStripeWidth;    //总体大小    private int mHeight;    private int mWidth;    //动画位置百分比进度    private int mCurPercent;    //实际百分比进度    private int mPercent;    //圆心坐标    private float x;    private float y;    //要画的弧度    private int mEndAngle;    //小圆的颜色    private int mSmallColor;    //大圆颜色    private int mBigColor;    //中心百分比文字大小    private float mCenterTextSize;    public MyView(Context context) {        this(context, null);    }    public MyView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        // 获取自定义属性        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyView, defStyleAttr, 0);        //获取色带的宽度        mStripeWidth = a.getDimension(R.styleable.MyView_stripeWidth, PxUtils.dpToPx(30, context));        //获取当前的百分比        mCurPercent = a.getInteger(R.styleable.MyView_percent, 0);        //获取小园的颜色        mSmallColor = a.getColor(R.styleable.MyView_smallColor, Color.BLACK);        //获取大圆的颜色        mBigColor = a.getColor(R.styleable.MyView_bigColor, Color.WHITE);        //获取中心文字的大小        mCenterTextSize = a.getDimensionPixelSize(R.styleable.MyView_centerTextSize, PxUtils.spToPx(50, context));        //获取园的半径        mRadius = a.getDimensionPixelSize(R.styleable.MyView_radius, PxUtils.dpToPx(100, context));    }    //测量    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        //获取测量模式        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        //获取测量大小        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        //如果为确定大小值,则圆的半径为宽度/2        if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) {            mRadius = widthSize / 2;            x = widthSize / 2;            y = heightSize / 2;            mWidth = widthSize;            mHeight = heightSize;        }        //如果为wrap_content 那么View大小为圆的半径大小*2        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {            mWidth = (int) (mRadius * 2);            mHeight = (int) (mRadius * 2);            x = mRadius;            y = mRadius;        }        //设置视图的大小        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onDraw(Canvas canvas) {        mEndAngle = (int) (mCurPercent * 3.6);        //绘制大圆        Paint bigCirclePaint = new Paint();        bigCirclePaint.setAntiAlias(true);        bigCirclePaint.setColor(mBigColor);        canvas.drawCircle(x, y, mRadius, bigCirclePaint);        //饼状图        Paint sectorPaint = new Paint();        sectorPaint.setColor(mSmallColor);        sectorPaint.setAntiAlias(true);        RectF rect = new RectF(0, 0, mWidth, mHeight);        canvas.drawArc(rect, 270, mEndAngle, true, sectorPaint);        //绘制小圆,颜色透明        Paint smallCirclePaint = new Paint();        smallCirclePaint.setAntiAlias(true);        smallCirclePaint.setColor(mBigColor);        canvas.drawCircle(x, y, mRadius - mStripeWidth, smallCirclePaint);        //绘制文本        Paint textPaint = new Paint();        String text = mCurPercent + "%";        textPaint.setTextSize(mCenterTextSize);        float textLength = textPaint.measureText(text);        textPaint.setColor(Color.RED);        canvas.drawText(text, x - textLength / 2, y, textPaint);        super.onDraw(canvas);    }    public void setmSmallColor(int mSmallColor) {        this.mSmallColor = mSmallColor;        invalidate();    }    //重置    public void setReset(int percent) {        mCurPercent = percent;        invalidate();    }    //外部设置百分比数    public void setPercent(int percent) {        if (percent > 100) {            throw new IllegalArgumentException("percent must less than 100!");        }        setCurPercent(percent);    }    //内部设置百分比 用于动画效果    private void setCurPercent(int percent) {        new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i < 101; i++) {                    mCurPercent = i;                    try {                        Thread.sleep(20);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    postInvalidate();                }            }        }).start();    }}

对应的布局 主页面 坑点  布局里面的Myview标签控件 根据自己的创建的类 自动生成 里面对应的dabin属性自定义的 别忘导包  对应的这个布局的宽度高度有如下一句话 

xmlns:dabin="http://schemas.android.com/apk/res-auto"


<?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"    xmlns:dabin="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.view.MainActivity">    <com.example.view.MyView        android:id="@+id/my_view"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        dabin:stripeWidth="15dp"        dabin:centerTextSize="16sp"        dabin:percent="78"        />    <Button        android:id="@+id/start"        android:text="开始"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="26dp"        android:layout_marginStart="26dp"        android:layout_marginBottom="117dp"        android:layout_alignParentBottom="true"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true" />    <Button        android:text="重置"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignBottom="@+id/start"        android:layout_alignParentRight="true"        android:layout_alignParentEnd="true"        android:layout_marginRight="51dp"        android:layout_marginEnd="51dp"        android:id="@+id/reset" />    <Button        android:text="改变外圈颜色"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_alignLeft="@+id/reset"        android:layout_alignStart="@+id/reset"        android:layout_marginLeft="19dp"        android:layout_marginStart="19dp"        android:layout_marginTop="56dp"        android:id="@+id/button2" /></RelativeLayout>
对应创建    一个转换Dip dp的的单位的类,可有可无,但是我对应的用了,这点根据自己需求 PxUtils

public class PxUtils {    public static int dpToPx(int dp, Context context) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());    }    public static int spToPx(int sp,Context context) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics());    }}
最后 就是对应的主方法 Activity

public class MainActivity extends AppCompatActivity {    private MyView myView;    private Button mButton;    private Button mReset;    private Button mColor;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        myView = (MyView) findViewById(R.id.my_view);        mButton = (Button) findViewById(R.id.start);        mReset = (Button) findViewById(R.id.reset);        mColor = (Button) findViewById(R.id.button2);        //开始        mButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                int n = (int) (Math.random() * 100);                myView.setPercent(n);            }        });        //重置        mReset.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                myView.setReset(78);            }        });        mColor.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                myView.setmSmallColor(Color.BLUE);            }        });    }}

 以上就能实现一个view圆  联动进度条  ,默认是78,转到100,有三个对应的按钮 点击 分别是重设 回到默认的 ,开始 :开始转动 ,第三个改变View的颜色


阅读全文
0 0
原创粉丝点击