Android开发之--自定义控件学习

刚开始接触Android时,看别人写的一个个自定义view感觉好牛逼,不甘落后的我自然也要学习下了,看到算法就头痛的我也只要硬着头皮上了,废话不说了,先来总结下自定义控件的基本步骤吧:

  1. 继承View完全自定义或继承View的派生子类
  2. 重写view的三个构造方法,在View的构造方法中获得我们自定义的属性
  3. 重写onDraw()进行绘图
    一个最基本的自定义控件肯定是离不来以上三个步骤的,至于还有其他的需求就需要重写其他的方法了,下面我来介绍下几个常用的方法
    onMeasure()
    这个方法是用在测量出view 的大小,根据测量view及其内容来确定view的宽度和高度。这个方法在measure(int, int)中被调用,必须被重写来精确和有效的测量view的内容,常用场景如测量listView的高度:
@Override  
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,  
            MeasureSpec.AT_MOST);  
    super.onMeasure(widthMeasureSpec, expandSpec);  
}

这句话是什么意思呢,makeMeasureSpec(size,mode),size不用我多说意思就是最大值啦,AT_MOST模式指的就是最大值模式,但是不会超过父控件允许的范围

onMeasure()
调用场景:在view给其孩子设置尺寸和位置时被调用。子view,包括孩子在内,必须重写onLayout(boolean, int, int, int, int)方法,并且调用各自的layout(int, int, int, int)方法。
参数说明:参数changed表示view有新的尺寸或位置;参数l表示相对于父view的Left位置;参数t表示相对于父view的Top位置;参数r表示相对于父view的Right位置;参数b表示相对于父view的Bottom位置。
onFinishInflate():
从xml加载主键后回调。意思就是说加载完xml就调用,可以初始化一些属性
onSizeChanged():
组件大小改变时调用,通常是在onMeasure()后面调用
onTouchEvent:
监听到触摸事件时回调
onDraw()
运行顺序如图:
这里写图片描述
对整个view的绘制方法全部在这个里面进行,这里就需要引入画布canvas以及paint画笔了,就好比画画,需要笔和纸是一样的。
canvas有很多好用的方法我就不一一说了,有兴趣的可以自己看,主要说说canvas的save(),restore():
save()顾名思义,有保存的意思,他的意思是保存前面代码的绘制,重新开一个画布
restore():合并画布的意思,就是把前面的画布合并到一块
还要说下:
incalidate():它代表手动调用onDraw();
下面上一个简单的自定义view,模仿音频条形图:
这里写图片描述
RectView

package com.example.administrator.xclcharts;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by Administrator on 2016/1/19.
 */
public class RectView extends View {
    private Paint paint;//画笔
    private float textHeight;//字体高度
    private float fontSize = getResources().getDimensionPixelSize(R.dimen.default_font_size);//字体大小
    private float  rectHeight;//矩形高度
    private Double mRandom;//随机数
    public RectView(Context context) {
        super(context);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);//设置为抗锯齿
        paint.setTextSize(fontSize);//设置字体大小

        //初始化textHeight
        textHeight = fontSize;
    }

    public RectView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RectView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int width = canvas.getWidth();//画布的宽高
        int height = canvas.getHeight();

//        paint.setColor(Color.BLUE);
//        canvas.drawText("11111111111", 100, 100, paint);
//        canvas.save();  //左上角 右下角
//        canvas.drawRect(100,100,200,200,paint);
      //  画坐标y轴
        canvas.drawLine(10, height-50, 10, 10, paint);
        //画x轴
        canvas.drawLine(10,height-50,width-10,height-50,paint);
        canvas.save();
        paint.setColor(Color.BLUE);
        //画刻度
        for (int i = 0; i<5;i++){
            canvas.drawLine(10, height-50,40,height-50,paint);
            //像y轴平移
            canvas.translate(0,-(height-50)/5);
        }
        canvas.restore();
        canvas.save();
        paint.setColor(Color.BLUE);
        //画刻度
        for (int i = 0; i<5;i++){
            canvas.drawLine(10,height-50,10,height-80,paint);
            //像x轴平移
            canvas.translate((width-10)/5,0);
        }
       canvas.restore();
        canvas.save();
//       // 画一个全白的矩形
//        paint.setColor(Color.WHITE);
//        canvas.drawRect(0,0,width,height,paint);
//        canvas.save();
        paint.setColor(Color.RED);
        //单个矩形的宽度
        int rectWidth =50;
        //矩形间间距
        int rectSpacing = 10;

        //
//        canvas.drawRect(20,50,20+rectWidth,height-50,paint);
//        canvas.drawRect(20+rectWidth+rectSpacing,50,20+rectWidth+(rectWidth+rectSpacing),height-50,paint);
//        canvas.drawRect(20+rectWidth+rectSpacing+(rectWidth+rectSpacing),50,20+rectWidth+(rectWidth+rectSpacing)+(rectWidth+rectSpacing),height-50,paint);
        //随机比例
       rectHeight = width;
        Log.e("RcetView", "onDraw---------rectHeight:"+rectHeight);
        for (int i =0;i<10;i++){
            mRandom = Math.random();
            Log.e("RectView", "width:" + width + "height:" + height+"mRandom"+mRandom);
            rectHeight = (float) (rectHeight * mRandom);
            canvas.drawRect(20 + (rectWidth + rectSpacing) * i, rectHeight, 20 + rectWidth + (rectWidth + rectSpacing) * i, height - 50, paint);
        }
        //postInvalidateDelayed(300);
   // canvas.restore();

    }
    //测量
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.e("RectView","onMeasure--------");

    }
    //设置布局
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        Log.e("RectView", "onLayout--------");
    }
    //初始化大小,
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        Log.e("RcetView", "onSizeChanged---------"+"w:"+w+"h:"+h+"oldw:"+oldw+"oldh:"+oldh);
    }
    //xml加载完后执行
    Timer timer;
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        Log.e("RcetView", "onFinishInflate---------");
        timer=new Timer();
        timer.schedule(task, 0, 1000);
    }
    TimerTask task=new TimerTask() {
        @Override
        public void run() {
            mHandler.sendEmptyMessage(0);
        }
    };
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
           invalidate();
        }
    };
}

代码比较乱。但是很简单,保留下,权当自学!自定义view水比较深,路漫漫其修远兮,只能慢慢来!
http://download.csdn.net/detail/wei8023hzp/9411885 下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值