Android 布局底部大按钮的实现,LinearLayout 对比 RelativeLayout

更新日期: 2022-03-01 阅读次数: 2661 字数: 1001 分类: Android

布局需求

一个植物种子图像识别的 Android APP,在功能页包含:

  • 底部一个大按钮,用于拍照
  • 顶部剩余区域展示选择的图片,及识别结果,例如自动识别出的种子个数

布局选型

网上搜了一下,发现可选的方案非常多。几乎各种 Layout 布局都有人采用,例如:

  • LinearLayout
  • RelativeLayout
  • FrameLayout
  • ConstraintLayout

从实现的角度,选择一个顺手的、方便自己理解的去用就行了。 但是作为 Android 萌新,我觉得还是有必要把各种 Layout 的实现方式都用一下, 相互对比,可以直观地理解不同 Layout 的特点,及其不同的使用场景。

LinearLayout 线性布局的实现 (个人最爱)

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:orientation="vertical"
    >
   <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />
    <Button
        android:id="@+id/btn_take_picture"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/take_picture" />
</LinearLayout>

效果如下:

这里的核心就是 LinearLayout 中 layout_weight 的使用。

而 layout_weight 有两种使用方式:

  • LinearLayout 中每个子 View 都设置了 layout_weight,这样大家按照各自的权重分割空间
  • LinearLayout 中部分 View 设置了 layout_weight,部分未设置。未设置的以自身高度或宽度占据空间,已设置的按照权重分割剩余的空间。即上面示例代码中的场景。

不设置 layout_height 高度会怎样?我测试了一下,从布局看似乎没啥影响;只不过 Android Studio 会提示没有设置 View 的高度。 所以还是加上吧,设置为 0dp 或 0px。

没想到如此简单就实现了效果,信心大增。再看看 RelativeLayout 如何实现吧。

RelativeLayout 相对布局的实现

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/btn_take_picture" />
    <Button
        android:id="@+id/btn_take_picture"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="@string/take_picture" />

</RelativeLayout>

RelativeLayout 的实现也非常简单直接,其核心布局思想就是相对于其他 View 的位置。

  • 底部按钮的位置由 layout_alignParentBottom,即对其父级 layout 的底部。
  • ScrollView 由 layout_above, 对其底部按钮的顶部。

唯一不好理解的地方是,ScrollView 的 height 为 match_parent,感觉不对劲。 但是效果是对的。

ConstraintLayout

在查看 Android 官方 RelativeLayout 的介绍时,发现官方更推荐使用 ConstraintLayout:

https://developer.android.com/training/constraint-layout

ConstraintLayout 可让您使用扁平视图层次结构(无嵌套视图组)创建复杂的大型布局。它与 RelativeLayout 相似,其中所有的视图均根据同级视图与父布局之间的关系进行布局,但其灵活性要高于 RelativeLayout,并且更易于与 Android Studio 的布局编辑器配合使用。

具体表现是:

  • 新建项目是默认引入了 ConstraintLayout 依赖:implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
  • 右键其他 Layout 可以自动转换为 ConstraintLayout

写代码不能光考虑性能,还要考虑维护性,当一个布局中到处都充斥着彼此依赖的关系,搞得增删一个控件就导致全盘皆崩,那我称这样的布局为一次性布局。你层级哪怕只有一级我也不会维护。这种想法就跟初学编程的时候,把所有代码写在一个方法里面一个意思。

客观讲,对于需要手动调整布局的方案,对我来说是减分项。 另外,确实相互间依赖,一旦删除一个元素怎么办。

寻找适合自己的技术方案,不要沦为大公司 KPI 技术方案的陪葬品。

大家说的效率对比,在我看来并没有啥对比价值。

ScrollView 与 ListView 的区别

这里的示例代码中都使用了 ScrollView,那么其与 ListView 的区别是什么呢?

  • ScrollView 的子元素可以是不同类型的 View。如果只是想要个滚动条,ScrollView 最合适。
  • ListView 的子元素需要是相同类型的 View。适合做数据列表展示。

当然,还有一个最大的区别:

  • ScrollView 的所有子元素都是放在内存中的
  • ListView 则是内存可回收,只把需要展示的部分放在内存中。所以数据列表规模巨大时,ListView 是唯一选择。

参考讨论: https://stackoverflow.com/questions/9820679/difference-between-scrollview-and-listview

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式