Android ViewGroup(Layout)使用注意事项(II)

作者: rain 分类: 移动 发布时间: 2011-11-21 19:50 6 条评论

前文中我们阐述了使用组合View的这种奇怪现象。出现这种问题的根源在于IconTextView类的实现,大部分的开发者认为使用IconTextView这种自定义View的方式 就相当于自定义了一个包含有一个ImageView和两个TextView的组合控件。 但是这里有个问题, 在View的层次结构中多出了一个LinearLayout。

仔细分析下, 我们的IconTextView类继承自LinearLayou,而布局文件icon_text_view.xml的根元素也是LinearLayou,这样我们的IconTextView的View关系就是两个Layout下面包含3个单个View。 使用Android的hierarchyviewer.bat工具可以查看到这种层次结构。

在icon_text_view.xml的布局文件中 我们指定了布局文件中的LinearLayout的android:focusable和android:clickable属性, 这样外面的自定义LInearLayou(上图中的IconTextView)就没法获取焦点和点击事件了,这样设置在IconTextView中的点击事件当然也无法响应了。

可以很明显的看到 有2个Layout存在。 当我们点击里面那个Layout的时候 可以具有Press状态响应,但是由于里面的Layout没有注册事件,所以不会有时间响应;如果我们设置外面的Layout可以响应点击事件,这样里面的Layou就不能响应Press状态了。从而出现这种Press状态显示和点击事件的响应不能同时实现的问题。

现在既然已经明白问题的根源了, 解决之道也是很容易的,把 icon_text_view.xml中的Layout删除 使用Android提供的marge元素就可以了,同时在IconTextView类中或者在添加该组合View到其他ViewGroup的时候指定其是可以获得焦点的就可以了。
最终解决代码如下:

布局文件 merge_icon_text_view.xml 使用marge来代替LinearLayout

自定义View类IconTextView, 不要忘记设置focusable属性

总结: 在使用自定义组合View的时候 注意ViewGroup的层次结构,如果引入了不必要的ViewGroup可以通过marge元素来消除。

更新: 也可以在布局文件中使用 自定义View的类名称, 例如把上面布局文件中的 merge 替换为: org.goodev.IconTextView.

本文出自 云在千峰,转载时请注明出处及相应链接。

本文永久链接: http://blog.chengyunfeng.com/?p=230

Ɣ回顶部