欢迎光临散文网 会员登陆 & 注册

DEVLOG 10.9 FrameLayout & addView

2021-10-09 19:58 作者:房顶上的铝皮水塔  | 我要投稿


问题1:在这段代码中 为什么不能将addView放到最底下?

如果将最后一行addView放到最底下,会出现NPE,表示layoutParams不能从textView中获取到。所以这个问题就转化成两个子问题:

  1. 原本的View中LayoutParams都是空的吗?

  2. addView是如何处理LayoutParams的呢?

1, View中的LayoutParams都是空的吗?

从文档中我们可以看出View#getLayoutParams方法会在两种情况下返回空:

- 如果当前的子View没有attach到ViewGroup

- 如果setLayoutParams没有正常生效


在View中,只有View#setLayoutParams将外界传入的View绑定到View的全局参数LayoutParams:

在绑定成功之后,会重新请求布局,所以ViewGroup会考虑更新之后的LayoutParams。

如果不使用setLayoutParams,View中的LayoutParams为空。(当然,如果通过解析xml的方式也算设置了LayoutParams)


所以,我们可以通过addView将子View添加到(attach)到ViewGroup,所以为了避免下面出现异常,我们需要先进行addView。

2, addView对于LayoutParams的处理

根据addView的重载方法来看,addView也有不接收LayoutParams的重载方法:

不过这个方法也会调用View#getLayoutParams。如果是直接指定宽高的addView重载,会生成默认的LayoutParams:


综上所述,上面的代码中没有必要使用LinearLayout.Params,因为GridLayout并没有重载addView,可以直接使用LayoutParams,不需要考虑子类。当然直接指定宽高的话也可以,代码可以这样写:

Scroller View#scrollTo  View#scrollBy  View#computeScroll

农夫三拳:Scroller#startScroll View#computeScroll postInvalidate

拿我在这篇文章画的这个图为例:

Scroller需要调用startScroll作为滑动开始信号,View中需要实现computeScroll计算是否完成滑动,然后调用自身scrollTo滑动到确定的位置,最后调用postInvalidate更新。


用invalidate也行,postInvalidate 和 invalidate的区别在于invalidate会立刻重绘,postInvalidate可以从非UI线程,发送一条消息到UI线程的Handler,再重绘View。

DEVLOG 10.9 FrameLayout & addView的评论 (共 条)

分享到微博请遵守国家法律