[译]Android开发之究竟使用哪个布局

本篇文章来讨论一个老生常谈却又时常困扰一些初学者的问题——该使用哪个布局管理器来实现用户界面。本篇文章适合于Android初学者阅读。
原文地址:https://medium.com/google-developers/layouts-attributes-and-you-9e5a4b4fe32c#.hr6f853fi
在这里感谢原作者的分享:)

什么是布局

若我们去Android开发者网站浏览一下,会发现大量以“Layout”结尾的类。那么它们有什么共同点呢?答案是它们都是ViewGroup的子类。也就是说它们都是一种布局管理器,这意味着它们都支持添加子View。
正如你所料,布局管理器的一个主要职责就是对它的子View进行布局,分为两个工作阶段来完成:

  • 决定它的每个子View分别多大,这个在测量(measure)阶段完成;
  • 把每个子View放到合适的位置上,这个在布局(layout)阶段完成。

当然,以上并不是布局管理器的全部职责。实际上,布局管理器还有其他的工作要做。
如果你想要以一个特定的方式对界面中的UI控件进行摆放,那么选择一个合适的布局管理器是很重要的。若选错了布局管理器,则可能会无法达到我们想要的布局效果,或者即使达到了,但是性能表现很差。有时,选对了布局管理器就能大大简化我们的工作。

布局属性

就像其他普通View一样,布局管理器也可以使用XML属性。比如LinearLayout的”android:orientation”属性,可以来指定摆放子View的方向——水平或是垂直,像这种属性是会影响到所有子View的全局属性。
有时我们想要使用只对特定子View生效的局部属性,这时“layout_”开头的XML属性就是我们的菜。

译者注:一个常见的例子就是”android:gravity”属性和“android:layout_gravity”属性,许多初学者都容易搞混这俩属性。实际上,前者是设置给布局管理器的,对于所有子View都生效;而后者是设置给子VIew的,只对设置了该属性的子View生效。

“layout_”系列属性就好比是对布局管理器的一系列指示,来看一个例子。

<android.support.design.widget.AppBarLayout>
  <android.support.v7.widget.Toolbar
    app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.AppBarLayout >

对于上面的“layout_scrollFlags”属性,无论我们尝试从Toolbar或是AppBarLayout入手,来寻找关于它的蛛丝马迹,我们对都不会找到什么。因为“layout_”系列属性实际存储在LayoutParams中,每个布局管理器都会关联一个LayoutParams实例,集中存放了子View对布局管理器的关于”如何对该子View进行布局”的指示。在上面的例子中,“layout_scrollFlags”位于AppBarLayout.LayoutParams中。默认情况下,LayoutParams中只含有“layout_width”和“layout_height”属性,但是每个布局管理器都可以向其中添加添加新的属性。

注意:上面的描述解释了,为什么从XML文件中加载一个没有父容器的View是一个糟糕的主意——没有父容器的话,就没人来解析“layout_”属性并创建一个合适的LayoutParams实例,那么所有“layout_”属性就相当于被丢弃了,这往往不是我们想要的。

常见Android布局管理器

理解了上面的内容,结合官方文档,我们就能够选择合适的布局管理器了。下面是对常见布局管理器的一个总结。

LinearLayout

LinearLayout的目标很明确:在单个行(水平方向)或是列(垂直方向)上摆放其子View。具体是水平还是垂直方向,由其“android:orientation”属性决定。
尽管LinearLayout已经有了如此明确的目标,我们仍能通过一些小把戏来达到一些其他效果。我们可以使用“layout_weight”属性让子View来扩展其尺寸,以填满所有剩余空间——这个特性当一些子View是“wrap_content”的,并且其他子View需要填满所有剩余空间时十分有用。

FrameLayout

FrameLayout与LinearLayout的布局效果大不相同。使用它,所有子View会“堆叠”在一起,这可能会发生互相重叠的现象。对子View摆放位置的唯一控制方式就是使用“layout_gravity”属性,可以实现把子View居中摆放或是贴着某一个边缘。

RelativeLayout

RelativeLayout比上面介绍的那俩要复杂些。如果我们看一下RelativeLayout.LayoutParams所包含的内容,会发现大量布局属性都是用来指定子View相对于RelativeLayout边缘或是RelativeLayout的其他子View的位置,这也就是它的名称(相对布局)的由来。
这种“相对布局”的特性十分有用,但我们在使用这个布局管理器时要注意性能问题。

PercentFrameLayout & PercentRelativeLayout

作为Percent Support Library的成员, PercentFrameLayout和PercentRelativeLayout在FrameLayout和RelativeLayout的基础上,支持基于百分比的尺寸。我们可以对它们使用”layout_widthPercent=50%”这样的布局属性。
它们还包含了另一个激动人心的特性——宽高比(aspect ratio)。这使得我们可以在布局文件中只声明子View的高度或宽度,另一个维度的尺寸可以根据指定的宽高比来动态改变。甚至在我们指定宽或高为“wrap_content”或“match_parent”时,这个特性也会生效。

GridLayout

GridLayout用来以“网格”的形式摆放子View。不像大多数布局管理器,我们甚至无需为其子View指定“layout_width”和“layout_height”,子View所占据的“网格”数目会根据它的Alignment来动态收缩。
在使用这个布局管理器之前,我强烈建议你阅读官方文档中关于GridLayout.LayoutParams的介绍,以及这篇博客

CoordinatorLayout

CoordinatorLayout是Android Design Support Library的一部分,它是FrameLayout的子类,因此具有FrameLayout的基本特性,但是它的不同之处在于支持“Behavior”。
通过为CoordinatorLayout的子View设置一个Behavior,就能够拦截在发生在这个子View上的一切(测量、布局、嵌套滚动、Touch事件等等)。
CoordinatorLayout最常用来实现其子View之间的交互行为。
想更深入的了解Behaviors,请戳拦截一切的Behavior

结语

即使只用上面提到的少数几个布局管理器,我们就能构造出酷炫、高性能的用户界面。下次你再纠结使用哪个布局管理器时,请仔细地考虑是否使用其他布局管理器会使得实现用户界面更为简单,或者使用自定义布局管理器是更好的方法。

CSDN正在举行博客之星评选,这里帮两位勤劳耕耘、帮助过许多Android初学者的大大打下广告,希望各位小伙伴可以支持一下。若没有CSDN账号,QQ登录即可投票。两位大大的投票地址如下:

长按或扫描二维码关注我们,让您利用每天等地铁的时间就能学会怎样写出优质app。

《[译]Android开发之究竟使用哪个布局》

    原文作者:absfree
    原文地址: https://www.jianshu.com/p/96b493ec8cd1
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞