Android 自定义View(一):对现有控件的扩展

一、View的测量

1.自定义View前首先要对View进行测量,即告诉系统应该画一个多大的View,这个过程在onMeasure()中进行

Android通过MeasureSpec类来帮助测量View。

2.MeasureSpec它有三种测量模式

EXACTLY:精确模式,当layout_height/layout_width属性为具体值或指定为match_parent时,为精确模式

AT_MOST: 最大值模式,当layout_height/layout_width属性为wrap_content时,控件大小随子控件变化,只要不超过父部件允许的尺寸即可

UNSPECIFIED:不指定其大小测量模式,View大小随意,通常自定义View下才使用

View的onMeasure()方法默认只支持EXACTLY模式,如果要让自定义View支持wrap_content就必须重写onMeasure()方法

二、View的绘制

View测量好之后,就要重写onDraw()方法来绘图

onDraw()方法中有一个参数canvas,通过这个对象就可以绘图了,而在其他地方需要创建一个Canvas对象

扫描二维码关注公众号,回复: 1723188 查看本文章

Canvas canvas = new Canvas(bitmap);

传进去的canvas与通过这个bitmap创建的Canvas画布是联系的一起的,此过程为装载画布。

这个bitmap用来存储绘制在canvas上的像素信息,如Canvas.drawXXX方法绘制的图会发生在这个bitmap上。

三、对现有控件扩展

通过继承系统组件,我们可以对现有控件扩展。

先介绍一下几个常用的回调方法

onFinishInflate()    //从XML加载组件后调用
onSizeChanged        //组件大小改变时回调
onMeasure            //回调该方法来进行测量
onLayout             //回调该方法来确定显示的位置
onTouchEvent         //监听触摸事件的回调
onDraw               //组件绘制时调用

自定义控件有三种方式

1.对现有控件进行拓展

2.通过组合来实现新的控件

3.重写View来实现全新的控件

四、举例

我们继承一个Button,在其四角画四个实心圆,在其中心画三个空心圆,并将背景改为粉红色

1.新建java类myButton,继承Button

记住要导入其构造方法

public MyButton(Context context) {
        super(context);
        initView();
    }

    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

2.声明画笔

因为onDraw方法中有canvas,所以只需要声明画笔即可

private Paint paint1,paint2;

设置画笔属性

private void initView() {
        paint1 = new Paint();
        paint1.setColor(getResources().getColor(android.R.color.holo_orange_light));
        paint1.setStyle(Paint.Style.FILL);          //实心
        paint2 = new Paint();
        paint2.setColor(getResources().getColor(android.R.color.holo_blue_bright));
        paint2.setStyle(Paint.Style.STROKE);        //空心
    }

3.重写onDraw方法

 /*
    * 程序调用super.onDraw(canvas);实现原生控件的功能,我们可以在其前后设计自己的控件*/
    @Override
    protected void onDraw(Canvas canvas) {
        //调用父类方法前,实现自己的逻辑,
        //四个实心圆
        canvas.drawCircle(0,0,30,paint1);
        canvas.drawCircle(0,getHeight(),30,paint1);
        canvas.drawCircle(getWidth(),0,30,paint1);
        canvas.drawCircle(getWidth(),getHeight(),30,paint1);
        //三个空心圆
        canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/8,paint2);
        canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/6,paint2);
        canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/4,paint2);
        //设置背景
        setBackground(getResources().getDrawable(R.color.colorAccent));
        canvas.save();               //保存画布
        super.onDraw(canvas);       //父类方法
        //调用父类方法后,实现自己的逻辑
        canvas.restore();            //合并图像
    }

5.引用

<myView.MyButton
        android:id="@+id/main_my_btn_expendView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ExpendView1"
        android:textAllCaps="false"
        android:layout_margin="10dp" />

效果

6.之后和正常的按钮一样实例化设置点击事件一样一样的


猜你喜欢

转载自blog.csdn.net/jinmie0193/article/details/80777331