1.自定义View构造方法
自定义View有三种构造方法:
第一种,参数为Context
;在代码里创建的时候调用;
第二种,参数为Context
和AttributeSet
;在布局中使用的时候调用;
第三种,参数为Context
,AttributeSet
和int
;在布局中使用的时候调用,并配合style
。
2.自定义View测量方法
自定义View的测量方法:
onMeasure(int widthMeasureSpec,int heightMeasureSpec)
作用:布局的宽高都是由该方法指定。
获取宽高的模式:
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
获取宽高的值:
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
自定义View测量的三种模式:
MeasureSpec.AT_MOST
:在布局中指定wrap_content
;
MeasureSpec.EXACTLY
:在布局中指定准确的值(100dp
),fill_parent
和match_parent
;
MeasureSpec.UNSPECIFIED
:尽可能大,很少用。使用情景:ListView
,ScrollView
在测量子布局的时候会使用。
源码晓课堂:
Q:ScrollView
嵌套ListView
为什么会出现显示不全的情况?
A:ScrollView
传给子控件的测量模式为MeasureSpec.UNSPECIFIED
,ListView
在MeasureSpec.getMode(heightMeasureSpec)
时走if(heightMode == MeasureSpec.UNSPECIFIED)
的判断条件,heightSize = mListPadding.top + mListPadding.bottom + childHeight + getVerticalFadingEdgeLength() * 2;
,最后setMeasuredDimension(widthSize,heightSize)
时 ,显示一个item
的高度,导致ListView
显示不全。
S:自定义ListView
,onMeasure
中重新设置heightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
Q:为什么要设置最大值右移两位?
A:因为要让ListView
不走if(returnHeight >= maxHeight)
的判断,返回returnHeight
,设置为Integer.MAX_VALUE
。
widthMeasureSpec,heightMeasureSpec
各包含两个信息是32位的值,第一个信息是模式:前2位,第二个信息是值:后30位。
3.自定义View绘制方法
自定义View
的绘制方法:
onDraw(Canvas canvas)
通过canvas
能绘制文字以及多种形状。
canvas.drawTest();
canvas.drawCircle();
canvas.drawRect();......
4.自定义View晓事件
自定义View
的触摸事件
onTouchEvent(MotionEvent event);
处理事件分发,与用户交互
switch(event.getAction()){
case MotionEvent.ACTION_UP:手指抬起
break;
case MotionEvent.ACTION_DOWN:手指按下
break;
case MotionEvent.ACTION_MOVE:手指移动
break;
}
4.自定义View晓属性
在res
下的values
文件下新建attr.xml
,写自定义View
的属性
<declare-styleable name="">
name——属性名称 format——格式
<attr name="text" format="String"/> 文字
<attr name="textColor" format="color"/> 颜色
<attr name="textSize" format="demension"/> 宽高 字体大小
<attr name="maxLength" format="integer"/> 数字
<attr name="background" format="reference|color"/> 资源(drawable)
<attr name="inputType" >
<enum name="number" value="1"/>
<enum name="text" value="2"/>
<enum name="password" value="3"/> 枚举
</attr>
</declare-styleable>
属性使用
在布局文件中:声明命名空间,在自定义View
中app:属性名=""
的方式使用
xmlns:app="http://schemas.android.com/apk/res-auto"
在类中:先在类中定义,再在构造方法中获取。
String mText;
......
TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.自定义View名称);
mText = array.getString(R.styleable.自定义View名称_属性名);
......
array.recycle();必须
备注:第一篇笔记,参考辉哥视频。