我们知道最基本的就是继承View,下面我们结合一个例子对重写进行简单地分析:
继承一个view,都会有一个或多个构造方法,在不同的时候调用到不同的构建方法,一般会重写三个方法,onMeasure();onLayout();onDraw();分别是测量,定位和画
下面说下,android中重写view时,经常会遇到的混淆:
requestLayout(),invalidate(),postInvalidate()方法
requestLayout:当view确定自身已经不再适合现有的区域时,该view本身调用这个方法要求parent view重新调用他的onMeasure onLayout来对重新设置自己位置。特别是当view的layoutparameter发生改变,并且它的值还没能应用到view上,这时候适合调用这个方法。
invalidate:是view调用本身的方法,强制view进行刷新,是用来刷新View的,必须是在UI线程中进行工作。比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。它是UI线程(即主线程)中调用,一般在代码中的handlermessage中,收到返回的消息调用。
postInvalidate:与invalidate相似,但是是在子线程中调用,相对来说比较简单。
最后我们就结合下面这个例子:讲解如果我们想在初始化的时候做一些操作,一般都会在里面写个方法,里面会new一个画笔,设置画笔的一些属性比如颜色,大小之类的。以及画布的旋转,平移之类的。
package com.example.demo;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class InfoDialView extends View{
private Paint percentPaint;
private Paint textPaint;
private int textSize = 50;
private int percent;
private int usedColor;
private int percentLineColorLow;
private int percentLineColorHight;
private int allLineWidth = 3;
private int percentLineWidth = 4;
private int lineHeight = 10;
private float maxValue = 100.00f;
private float curValue = 0.00f;
private int tipTextSize = 15;
private Bitmap icon;
public InfoDialView(Context context) {
super(context);
init(null, 0);
}
public InfoDialView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public InfoDialView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs,defStyle);
init(attrs,defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
// TODO Auto-generated method stub
final TypedArray a = getContext().obtainStyledAttributes(
attrs, R.styleable.InfoDialView, defStyle, 0); //得到一些自定义属性
maxValue = a.getFloat(R.styleable.InfoDialView_maxValue, 0.0f);
curValue = a.getFloat(R.styleable.InfoDialView_currentValue, 0.0f);
usedColor = a.getColor(R.styleable.InfoDialView_usedColor, Color.GRAY);
percentLineColorLow = a.getColor(R.styleable.InfoDialView_percentLineColorLow, Color.GREEN);
percentLineColorHight = a.getColor(R.styleable.InfoDialView_percentLineColorHight, Color.RED);
a.recycle(); //不要忘记回收
percent = (int)(curValue*100/maxValue);
percentPaint = new Paint();//设置画笔
percentPaint.setAntiAlias(true);
textPaint = new Paint();
textPaint.setTextSize(textSize);
textPaint.setAntiAlias(true);
icon = BitmapFactory.decodeResource(getResources(), R.drawable.icon_syrl);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int pointX = width/2;
int pointY = height/2;
float textWidth = textPaint.measureText((maxValue-curValue)+"");
textPaint.setColor(Color.WHITE);
canvas.drawText((maxValue-curValue)+"",pointX - textWidth/2,pointY + textPaint.getTextSize()/2 ,textPaint);
Paint paint = new Paint();
paint.setTextSize(tipTextSize);
paint.setAntiAlias(true);
float tipW = paint.measureText("剩余热量(kwh)");
paint.setColor(Color.WHITE);
canvas.drawBitmap(icon, pointX -icon.getWidth()/2-tipW/2-15,pointY - textPaint.getTextSize()/2-13-icon.getHeight()/2, null);
canvas.drawText("剩余热量(kwh)", pointX-tipW/2, pointY - textPaint.getTextSize()/2-paint.getTextSize()/2, paint);
if(percent<80){
percentPaint.setColor(percentLineColorLow);
}else{
percentPaint.setColor(percentLineColorHight);
}
percentPaint.setStrokeWidth(allLineWidth);
float degrees = (float) (320.0/100);
canvas.save();
//在旋转画布前先保存画布,不然原来画得可能找不到了。
canvas.translate(0,pointY);
canvas.rotate(-70, pointX, 0);
for(int i = 0;i<100;i++){
canvas.drawLine(0, 0, lineHeight, 0, percentPaint);
canvas.rotate(degrees, pointX, 0);
}
canvas.restore(); //重新加载之前保存的画布,一个save,都会有个resore与之对应
percentPaint.setColor(usedColor);
percentPaint.setStrokeWidth(percentLineWidth);
canvas.save();
canvas.translate(0,pointY);
canvas.rotate(-70, pointX, 0);
for(int i = 0;i<percent;i++){
canvas.drawLine(0, 0, lineHeight, 0, percentPaint);
canvas.rotate(degrees, pointX, 0);
}
canvas.restore();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//测量
// TODO Auto-generated method stub
//super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int d = (width >= height) ? height : width;
setMeasuredDimension(d,d);
}
public void setValue(float maxValue,float currentValue) {//供外部调用的方法
this.maxValue = maxValue;
this.curValue = currentValue;
postInvalidate();
}
}
有问题,欢迎大家私信交流。。。
版权声明:本文为博主原创文章,未经博主允许不得转载。