码迷,mamicode.com
首页 > 其他好文 > 详细

简单的重写控件

时间:2015-07-19 18:17:00      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:重写控件   自定义控件   

我们知道最基本的就是继承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();
}
}


有问题,欢迎大家私信交流。。。


版权声明:本文为博主原创文章,未经博主允许不得转载。

简单的重写控件

标签:重写控件   自定义控件   

原文地址:http://blog.csdn.net/u013377714/article/details/46955025

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!