3.6.3 重写View来实现全新的控件
当android原生控件无法满足我们的要求的时候,我们可以实现一个新的自定义控件来实现需要的功能。通常我们需要通过继承View,重写onMeasure(),onDraw()等方法来实现绘制逻辑,通过重写onTouchEvent()等触控事件来实现交互逻辑,同时我们也可以像组合控件那样,引入自定义属性,丰富自定义View的可定制性
3.6.3.1 弧线展示图
接下来我们实现这样的一个自定义控件
分析:这个控件由三部分组成:弧形 圆形 文字
我们只需要分别绘制这三个基本的图形就ok了
1.实现onMeasure() 测量大小
2.实现onDraw()绘制图形
3.实现某些可供用户调用的公有方法如setSweepValue()
4.实现交互功能
代码示例
package com.example.phonejason;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by 小新 on 2016/6/9.
*/
public class canvas extends View {
//屏幕的宽度和高度
private int mMeasureWidth,mMeasureHeight;
//圆形、文字、弧形画笔
private Paint mCirclePaint,mTextPaint,mArcPaint;
//圆形的圆心x,y坐标以及半径
private float mCircleXY,mCircleRadius;
//展示的文字
private String mShowText;
//文字的大小
private int mShowTextSize;
//弧形的外接矩形
private RectF mArcRectf;
//弧的扫过的度数
private float mSweepAngle;
private float mSweepValue=66;
public canvas(Context context) {
super(context);
}
public canvas(Context context, AttributeSet attrs) {
super(context, attrs);
}
public canvas(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//1.自定义图形第一步:测量大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mMeasureWidth = MeasureSpec.getSize(widthMeasureSpec);
mMeasureHeight = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(mMeasureWidth,mMeasureHeight);
initView();
}
//3、实现绘画
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(mCircleXY,mCircleXY,mCircleRadius,mCirclePaint);
canvas.drawArc(mArcRectf,270,mSweepAngle,false,mArcPaint);
canvas.drawText(mShowText,0,mShowText.length(),mCircleXY,mCircleXY+mShowTextSize/4,mTextPaint);
}
//2.初始化:绘画的圆心,弧形,文字的各个属性,画笔的属性
private void initView() {
float length;
if(mMeasureWidth>mMeasureHeight){
length = mMeasureHeight;
}else {
length = mMeasureWidth;
}
//设置圆形的圆心、半径
mCircleXY = length/2;
mCircleRadius = length/2/2;
mCirclePaint = new Paint();
//设置抗锯齿
mCirclePaint.setAntiAlias(true);
mCirclePaint.setColor(Color.BLUE);
//设置外接矩形
mArcRectf = new RectF((float)(length*0.1),(float)(length*0.1),(float) (length*0.9),(float) (length*0.9));
mSweepAngle = (mSweepValue/100f)*360f;
mArcPaint = new Paint();
mArcPaint.setColor(Color.BLUE);
mArcPaint.setAntiAlias(true);
mArcPaint.setStrokeWidth((float)(length
*0.1));
mArcPaint.setStyle(Paint.Style.STROKE);
//设置文字
mShowText = setShoeText();
mShowTextSize = setShowTextSize();
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextAlign(Paint.Align.CENTER);
}
//文字的大小,可传入参数然后修改
private int setShowTextSize() {
this.invalidate();
return 50;
}
//文字的内容,可传入参数然后修改
private String setShoeText() {
this.invalidate();
return "xiaoxin";
}
//提供给用户的公有方法可以修改属性(java中调用) 也可以通过自定义属性在xml中设置
public void setSweepValue(float sweepValue) {
if (sweepValue != 0) {
mSweepValue = sweepValue;
} else {
mSweepValue = 25;
}
this.invalidate();
}
}
布局
<com.example.phonejason.canvas
android:id="@+id/canvas"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
activity中
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mycanvas = (com.example.phonejason.canvas) findViewById(R.id.canvas);
mycanvas.setSweepValue(10);
}
总结:自定义view的话我们需要一步一步来,从一个基本的效果开始,满满增加功能,绘制更复杂的效果(PS:上面这个Demo没有实现交互功能)
补充一个小知识点:
Matrix类:这个类是矩阵,在图像处理方面用于平面的缩放、平移、旋转、错切等操作,是一个3*3由9个float值构成;具体参考别人的博客