View 自定义 - View 体系和方法

一、概念

View 自定义 - View 体系和方法_第1张图片

View 代表用户界面组件的基本构建块,在屏幕上占据一个矩形区域并负责绘制和事件处理,是用于创建交互式用户界面组件(按钮、文本等)的基础类,因此我们使用的各种控件其实就是在 View 的基础上又添加了各自特有的功能。
ViewGroup 继承自View,它可以包含很多子View和子ViewGroup,是一个用于放置控件和布局的容器。

二、类中方法

构造

View(Context context)

单参构造:代码中 new 创建实例的时候调用。

View(Context context, AttributeSet attrs)

双参构造:xml中使用时调用(xml转java代码的时候反射),attrs是xml中的属性。

View(Context context, AttributeSet attrs, int defStyleAttr)

三参构造:使用主题Style的时候调用。

绘制过程

onFinishInflate()

当View和他的所有子控件被XML布局文件填充完成时被调用。(这个方法里面可以完成一些初始化,比如初始化子控件)。

onMeasure()

当测量View和它的子View的尺寸需求时被调用。

onLayout()

当View给他的子View分配大小和位置的时候调用。

onSizeChanged()

当view尺寸发生变化时调用。

事件处理

onKeyDown(int keyCode, KeyEvent event)

按下按键时调用,keyCode是按键编号,KeyEvent是按键事件。

onKeyUp(int keyCode, KeyEvent event)

抬起按键时调用。

onTouchEvent(MotionEvent event)

触摸屏幕时调用,MotionEvent是捕捉到的触摸事件。

焦点

onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect)

获取到或者失去焦点时调用。

onWindowFocusChanged(boolean hasWindowFocus)

窗口获取或者失去焦点时调用。

attach

onAttachedToWindow()

当View被连接到一个窗口时调用。

onDetachedFromWindow()

当View从窗口分离时调用。

onWindowVisibilityChanged()

当View的窗口的可见性发生改变时调用。

2.1 构造

没有空参构造必须重写,一共有四种(四参构造在 API21 加入)对应不同的创建方式。一般只需要重写前三个,通过 this 调用到三参构造中统一进行处理。

View(Context context)

单参构造:代码中 new 创建实例的时候调用。

View(Context context, AttributeSet attrs)

双参构造:xml中使用时调用(布局文件映射成java对象,反射),attrs是xml中的属性需要解析。

View(Context context, AttributeSet attrs, int defStyleAttr)

三参构造:使用主题Style的时候调用。

class MyView : View {
    //改成this调用2个参数的构造
    constructor(context: Context?) : this(context, null)
    //改成this调用3个参数的构造
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    //在3个参数的构造里统一进行处理
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        //TODO...
    }
}

2.2 绘制过程

onFinishInflate() 当View和他的所有子控件被XML布局文件填充完成时被调用。(这个方法里面可以完成一些初始化,比如初始化子控件)。
onMeasure() 当测量View和它的子View的尺寸需求时被调用。
onLayout() 当View给他的子View分配大小和位置的时候调用。
onDraw() 当绘制View时调用。
onSizeChanged() 当view尺寸发生变化时调用。

2.3 事件处理

onKeyDown()

onKeyDown(int keyCode, KeyEvent event)

按下按键时调用,keyCode是按键编号,KeyEvent是按键事件。

onKeyUp()

onKeyUp(int keyCode, KeyEvent event)

抬起按键时调用。

onTouchEvent()

onTouchEvent(MotionEvent event)

触摸屏幕时调用,MotionEvent是捕捉到的触摸事件。(当View带有滑动嵌套情况时,必须要处理好滑动冲突,否则会严重影响View的显示效果。)

2.4 子元素

添加子元素,除了在 xml 中包裹,还能用如下代码添加。

removeView()

public void removeView(View view)

移除某个子元素。

removeAllViews()

public void removeAllViews()

清空所有子元素。

addView()

public void addView(View child)

添加子元素。

fun setData(list: List) {
    removeAllViews()
    for(i in list) {
        val textView = TextView(getContext())
        textView.text = list[i]
        addView(textView)
    }
}

五、焦点

onFocusChanged()

onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect)

获取到或者失去焦点时调用。

onWindowFocusChanged()

onWindowFocusChanged(boolean hasWindowFocus)

窗口获取或者失去焦点时调用。

findFocus()

public View findFocus()

获取当前拥有焦点的控件,注意空判断。

六、避免内存泄漏 attach

针对View中含有线程或动画的情况:当View退出或不可见时,记得及时停止该View包含的线程和动画,否则会造成内存泄露问题。

onAttachedToWindow() 当包含该View的Activity启动的时调用,可用于启动线程/ 动画。
onDetachedFromWindow() 当包含该View的Activity退出或该View被remove的时调用,可用于停止线程/动画。
onWindowVisibilityChanged() 当包含该View的窗口的可见性发生改变时调用。

七、多线程

View的内部本身提供了post系列的方法,完全可以替代Handler的作用,使用起来更加方便、直接。

post()

你可能感兴趣的:(View,android)