可能小伙伴们感觉自定义view很高深,其实大家用多了别人的轮子,研究别人的轮子,自己也要学着造轮子,那就用最简单的练练手,教小伙伴们自定义view的一些步骤,这可能是小伙伴们最需要的。
自定义圆环
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import org.w3c.dom.Attr;
import example.com.mvpdesign.R;
/**
* Created by qiang.lin
*/
public class RingView extends View {
//画笔
private Paint mPaint;
//圆环的颜色
private int ringColor;
private int width;
private int high;
private int center;
public RingView(Context context) {
this(context, null);
}
public RingView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
//看了很多自定义view,也用了很多自定义view,View是会自动//调用带有两个参数的构造器,但是我看了大神的的代码,基本上都是指//向三个构造器。
public RingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取自定义的属性,并赋予初始值。
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RingView);
ringColor= typedArray.getColor(R.styleable.RingView_ringColor, Color.RED);
textSize= typedArray.getDimensionPixelSize(R.styleable.RingView_ringText, 20);
typedArray.recycle();
//初始化画笔
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setDither(true);
mPaint.setAntiAlias(true);
}
//这里获取canvas的高度和宽度,没有使用到,但是经常会使用到,可以研究下。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
center = getWidth() / 2;
width = getWidth();
high = getHeight();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//半径
int innerCircle=60;
//圆环宽度
int ringWidth=30;
//绘制圆环
mPaint.setColor(ringColor);
//画笔的笔触是在宽度的中间,所以后面需要
// ringWidth/2,这个才是真实半径
mPaint.setStrokeWidth(ringWidth);
canvas.drawCircle(200,200,innerCircle+ringWidth,mPaint);
//重绘ondraw方法,这个方法就是相当于刷新
invalidate();
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
配置文件
<declare-styleable name="RingView">
<attr name="ringColor" format="color"></attr>
<attr name="ringText" format="dimension"></attr>
</declare-styleable>
配置文件在最顶部加上这句
xmlns:app="http://schemas.android.com/apk/res-auto"
这里一个自定义的圆环就完成了。下面来看看自定义圆环进度条。
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.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;
import example.com.mvpdesign.R;
/**
* Created by qiang.lin
*/
public class RoundProgressBar extends View {
private int textSize;
private int textColor;
private int ringColor;
private int progressColor;
private int width;
private int high;
private Paint mPaint;
private int progress=50;
private int max=100;
public RoundProgressBar(Context context) {
this(context, null);
}
public RoundProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//初始化自定义属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar);
textSize = typedArray.getDimensionPixelSize(R.styleable.RoundProgressBar_textSize, 50);
textColor = typedArray.getColor(R.styleable.RoundProgressBar_textColor, Color.RED);
ringColor = typedArray.getColor(R.styleable.RoundProgressBar_ringColors, Color.CYAN);
progressColor = typedArray.getColor(R.styleable.RoundProgressBar_progessColor, Color.BLUE);
typedArray.recycle();
//初始化画笔
mPaint = new Paint();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
high = getHeight();
width = getWidth();
//内容的半径
// center=getWidth()/2;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画背景的圆环,获取的是画布的宽度
int roundWidth = 10;
int center = getWidth() / 2;//圆心
int radius = center - roundWidth /2-5;
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(ringColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(roundWidth);
canvas.drawCircle(center, center, radius, mPaint);
//画进度条变分比。
mPaint.setStrokeWidth(0);
mPaint.setColor(textColor);
mPaint.setTextSize(textSize);
mPaint.setTypeface(Typeface.DEFAULT_BOLD);
int percent = (int) (((float) progress / (float) max) * 100);
float textWidth = mPaint.measureText(percent + "%");
if(percent!=0){
canvas.drawText(percent+"%",center-textWidth/2,center+textSize/2,mPaint);
}
//画进度条
mPaint.setStrokeWidth(roundWidth);
mPaint.setColor(progressColor);
//画圆形的区域。
RectF oval=new RectF(center-radius,center-radius,center+radius,center+radius);
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawArc(oval, 90, -360 * progress / max, false, mPaint); //根据进度画圆弧
invalidate();
}
public int getTextSize() {
return textSize;
}
//通过代码来设置字体大小。
public void setTextSize(int textSize) {
this.textSize = textSize;
//重新绘制,走ondraw()
invalidate();
}
}
<declare-styleable name="RoundProgressBar">
<attr name="textSize" format="dimension"></attr>
<attr name="ringColors" format="color"></attr>
<attr name="progessColor" format="color"></attr>
<attr name="ringWidth" format="dimension"></attr>
<attr name="textColor" format="color"></attr>
</declare-styleable>
完事,自定义View——圆环进度条就这样完成了。
总结:自定义view步骤:
1、继承View
2、重写onMeasure和onDraw方法。
3、在调用三个参数构造器,在里面做初始化自定义属性,前提需在attrs xml文件下创建自定义属性。并实例化Paint
4、在onDraw方法里开始你的画画,一大堆数学问题等着你,就是算。
5、设置你的属性的get和set方法,然后再set方法里 invalidate();,好的自定义View就这样完成了。
建议:有些系统类可能大家不是很清楚,可以上网百度,或者直接进入源码,看看源码是怎么讲的,用多了就熟了。
以上如有不恰当之处,评论可给予提出。