android开发篇之自定义View

控件有很多属性,如android:id、android:layout_width、android:layout_height等,但是这些属性都是系统自带的属性。使用attrs.xml文件,可以自己定义属性。



看这张要实现的自定义控件, 要实现这个效果就必须使用自定义属性,将TextView的功能和圆环的功能绑定在一起!组成一个控件 ,代码如下所示。

首先:在Value文件下定义一个attrs.xml文件


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RoundProgress">
        <attr name="roundColor" format="color"/>
        <attr name="roundProgressColor" format="color"/>
        <attr name="roundWidth" format="dimension"></attr>
        <attr name="textColor" format="color"/>
        <attr name="textSize" format="dimension"/>
    </declare-styleable>
</resources>


然后,将这个attrs.xml文件引用到布局文件(home_frahment),这里只截取部分

  <!-- 圆环进度-->
                <cn.itcast.wh.p2pmoney12.ui.RoundProgress
                    android:id="@+id/p_progresss"
                    android:layout_width="120dp"
                    android:layout_height="120dp"
                    app:roundColor="@android:color/darker_gray"
                    app:roundProgressColor="@android:color/holo_red_dark"
                    app:roundWidth="10dp"
                    app:textColor="#18b4ed"
                    app:textSize="20sp">
                </cn.itcast.wh.p2pmoney12.ui.RoundProgress>

默认实现效果如图:

当然重点就在

cn.itcast.wh.p2pmoney12.ui.RoundProgress的实现上了,具体代码如下:
package cn.itcast.wh.p2pmoney12.ui;

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.view.View;

import cn.itcast.wh.p2pmoney12.R;

/**
 * Created by Administrator on 2015/12/13.
 */
public class RoundProgress extends View {

    private Paint paint = new Paint();

    private int roundColor;
    private int roundProgressColor;
    private int textColor;
    private float textSize;
    private float roundWidth;
    private int max = 100;

    private int progress = 50;

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

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

    public RoundProgress(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgress);
        //圆环的颜色,颜色首先会从R.styleableRoundProgress_roundColor下去寻找(RoundProgress_roundColor是在attrs.xml文件下定义,
        // 但是是在home_fragment.xml中的<cn.itcast.wh.p2pmoney12.ui.RoundProgress完成赋值,放到了R.1java文件中去了),没有找到就会使颜色用Color.RED
        roundColor = mTypedArray.getColor(R.styleable.RoundProgress_roundColor, Color.RED);
        //圆环进度的颜色
        roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgress_roundProgressColor, Color.GREEN);
        //中间进度百分比文字字符串的颜色
        textColor = mTypedArray.getColor(R.styleable.RoundProgress_textColor, Color.GREEN);
        //中间进度百分比的字符串的字体大小
        textSize = mTypedArray.getDimension(R.styleable.RoundProgress_textSize, 15);
        //圆环的宽度
        roundWidth = mTypedArray.getDimension(R.styleable.RoundProgress_roundWidth, 5);
        mTypedArray.recycle();
    }


    @Override
    protected void onDraw(Canvas canvas) {
        //第一步:绘制一个最外层的圆
        paint.setColor(roundColor);
        paint.setStrokeWidth(roundWidth);//设置线宽(形象地理解为,大圆和小圆半径之差)
        paint.setStyle(Paint.Style.STROKE);//指定圆为空心,如果为实心的话,就一坨饼。
        paint.setAntiAlias(true);//去掉锯齿效果(圆默认都会带有锯齿效果的)
        int center = getWidth() / 2;//得到当前View的宽度的一半
        int radius = (int) (center - roundWidth / 2);//得到半径
        canvas.drawCircle(center, center, radius, paint);//画圆

        //第二步:绘制正中间的文本
        float textWidth = paint.measureText(progress + "%");
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        paint.setStrokeWidth(0); //注意这里要将线宽设置为很低或者0,否则你会发现运行出来的TextView为一坨饼
        canvas.drawText(progress + "%", center - textWidth / 2, center + textSize / 2, paint);

        //第三步:绘制弧形
        /**
         * 参数解释:
         * oval:绘制弧形圈所包含的矩形范围轮廓(在圆环的内部)
         * 0:开始的角度
         * 360 * progress / max:扫描过的角度
         * false:是否包含圆心(如果包含圆心,你会发现画出来的图,很恶心。)
         * paint:绘制弧形时候的画笔
         */
        RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius);
        paint.setColor(roundProgressColor);
        paint.setStrokeWidth(roundWidth);
        paint.setStyle(Paint.Style.STROKE);//设置为空心
        canvas.drawArc(oval, 0, 360 * progress / max, false, paint); //画弧形
    }

    public void setProgress(int progress){
        this.progress = progress;
        if(progress>100){
            this.progress = 100;
        }
        postInvalidate(); //调用这个方法就会重新调用onDraw(),再一次画图。
    }
}


最后,在Fragment中将这个View显示出来。



总体实现逻辑就是:

1.看这个控件是否需要使用自定义属性,具体参考请看:上面红色部分

2.将这个attrs.xml文件引入到正在使用的布局中

3.在java文件中,使用自定义View,将这个控件“画”出来。



猜你喜欢

转载自blog.csdn.net/cdaimadada/article/details/80717115