总是看着别人写博客,而自己也不知道如何下手,今天终于鼓起勇气写了我自己的博客,希望对大家有所帮助哦!
一、看着别人的自定义控件,我们很是好奇,但是我们怎么自定义控件呢?
我们首先先要理解什么是自定义控件,
广义上来讲自定义控件无非有四种
1、继承View类或者继承ViewGroup类来完成
2、继承系统为我们提供好的类(例如:五大布局、TextView、Button、ImageView等...)
3、自定义组合控件
但是无论你继承哪一个类,归根接地我们的控件最继承父控件的都是View,而无论是ViewGroup还是Google为我们提供的控件都是在继承其父控件的基础上进行了更加强大得功能的封装,
我们如何选择继承自哪种类呢?
这就取决于我们的业务需要如何样式的自定义控件了
二、简单的步骤使用介绍(后期我会根据不停地自定义控件来再次详细的介绍哦!)
1、首先我们创建一个类继承我们在上面讲解的三种类型之中的一个类
2、我们重写构造方法(构造方法有三个根据需要重写不同的方法)
①.带有一个参数的构造方法作用:
当
我们在new对象的时候调用该方法。
②.带有两个参数的构造方法作用:
AttributeSet这个参数代表属性集合,意思就是当你在布局文件使用这个自定义控件时,系统解析xml文件的时候,解析你的自定义控件节点时,系统会调用第二个构造方法
辣么问题来了,系统是怎么调用第二个构造方法的呢?
嘻嘻,请容我来给大家讲一讲
系统会根据你给它指定的标签(也就是这个类的类名),使用Java的反射机制,创建该对象,接着解析里面的每一个属性和属性值,
封装到第二个参数里面(AttributeSet属性集合),然后动态的赋值给该对象
恶补一下Java的反射机制的作用
Java的反射机制作用:可以动态的给这个对象赋值、方法和属性值
③.带有三个参数的构造方法作用:
这个方法不会被系统调用,只能被我们自己调用,调用这个方法给控件指定默认的样式
辣么我又不知道怎么调用第三个构造方法啦?
我们可以这么干,
1、我们可以在带有一个参数的构造方法里面把super(context);删掉,通过this.(context, null);调用第二个构造方法,
2、在带有第二个参数的构造方法里面
把super(context, attrs);删掉,
通过this.(context, attrs, 0);调用第三个构造方法
这样就能够保证我们无论是new该对象,还是在xml文件中使用该对象,都可以保证第三个构造方法被调用
方法如下:
public 类名(Context context) {
super(context);
}
public 类名(Context context, AttributeSet attrs) {
super(context, attrs);
}
public 类名(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
3、我们根据自己的需求可以自己进行显示操作
绘制显示的流程
①.测量(控件的宽高)
②.排版(设置控件的位置)
③.绘制(根据控件的宽高以及显示的位置进行绘制显示)
我们这三步不能随便写,这是Google给我们的规范,必须要等到先测量,在排版,最后绘制的顺序执行,这样才能绘制出我们想要的自定义控件
方法介绍如下:
/**
* 测量:测量控件的宽高
* @param widthMeasureSpec 表示我们的控件在布局文件中的宽
* @param heightMeasureSpec 表示我们的控件在布局文件中的高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 排版:设置控件的位置
* @param changed
* @param left
* @param top
* @param right
* @param bottom
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
/**
* 绘制:根据测量控件的宽高和控件的位置绘制出控件
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
如果大家有什么疑问,请在下面留言,我会为大家解答的!
后期还会有其他的具体实现介绍哦!感谢大家的关注哦!