Android学习记录自定义view

自定义View的学习笔记

一、自定义View的三个方法:

1、measure

a、SpecMode有三种类型:

UNSPECIFIED :父容器不对View有任何限制,要多大给多大,这种情况一般用于系统内部,自定义的时候用途不大;

EXACTLY: 精确大小,对应LayoutParams中的固定值或者match_parent;

AT_MOST:View大小不能大于父容器的大小,对应LayoutParams中的wrap_content;

b、系统内部通过MeasureSpec进行View的测量,但是我们可以给View设置LayoutParams,在View测量的时候,系统会将LayoutParams转换成对应的MeasureSpec,然后根据MeasureSpec来确定View测量后的宽和高。MeasureSpec是由父容器和LayoutParams一起决定。

c、自定义布局的一些整理:

1)自定义控件继承View如果要使wrap_content生效需要自定义onMeasure方法处理AT_MOST,padding和margin生效需要在draw方法里进行处理,

2)自定义View继承ViewGroup需要实现onMeasure以及OnLayout方法参考LinearLayout

d、获取View宽高的一些方法

1)onWindowFocusChanged

需要注意的问题该方法在Activity获取和失去焦点时都会调用。

2)使用View.post(runnable)

通过post可以将runnable添加到消息队列的尾部,等Looper调用此runnable的时候,View已经初始化好了

3)ViewTreeObserver

ViewTreeObserver的众多回调接口都可以获取view宽高,如OnGlobalLayoutListener在onGlobalLayout方法中可以获取,需要注意的是随着View树的改变,该方法会调用多次

4)View.measure(int widthMeasureSpec, int heightMeasureSpec)

通过手动调对view进行measure可以得到view的宽高

math_parent如果不知道父容器的大小就不行

具体数值可以通过以下方法计算

int widthMeasureSpec = MeasureSpec.makesureSpec(100, MeasureSpec.EXACTLY);

int heightMeasureSpec = MeasureSpec.makesureSpec(100, MeasureSpec.EXACTLY);

view.measue(widthMeasureSpec, heightMeasureSpec);

wrap_content 如下方式获得:

int widthMeasureSpec = MeasureSpec.makesureSpec(1 << 30, MeasureSpec.EXACTLY);

int heightMeasureSpec = MeasureSpec.makesureSpec(1 << 30, MeasureSpec.EXACTLY);

view.measue(widthMeasureSpec, heightMeasureSpec);

2、layout

View layout方法流程:

首先通过setFrame方法设定View的四个顶点的位置,这个点的位置一确定他在父容器的位置也就确定了

ViewGroup layout方法流程:

遍历所有子元素并调用setChildFrame方法为子元素指定对应位置,父元素在layout方法中完成自己的定位后就通过调用子元素的layout方法确定子元素的位置,这样一层层的传递就完成了整个viewGroup的定位。

测量宽高不一定是最终宽高的原因1、有的View需要进行多次测量才能,最终的测量宽高还是等于实际宽高2、自定义layout可实现测量宽高不等于最终宽高。

3、draw过程

a、绘制背景background.draw

b、绘制自己

c、绘制children(dispatchDraw)

d、绘制装饰(onDrawScrollBars)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值