Android 硬布局 item 的高级写法
- 2022 年 6 月 24 日
本文字数:5452 字
阅读完需:约 18 分钟
效果:
这种布局应该是非常常见了,且写的比较多。
今天简单探讨一下效果图中上下两种布局的写法。
比较
可以看出,对比还是很明显的,精简到最后只有最开始的四分之一。
上部分
先看常规 item 写法,横向的 LinearLayout 嵌套三个子 View,分别是
左边的 ImageView,
中间的 TextView,
和右边的 ImageView。
然后每个横向的 LinearLayout 之间添加一个高度 1dp 的 View 来作为横线。
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/dp_15" android:layout_marginTop="@dimen/dp_20" android:layout_marginEnd="@dimen/dp_15" android:layout_marginBottom="@dimen/dp_20" android:background="@drawable/shape_bg_white" android:orientation="vertical">
<LinearLayout android:id="@+id/ll1" android:layout_width="match_parent" android:layout_height="wrap_content" android:foreground="?android:attr/selectableItemBackground" android:gravity="center_vertical" android:orientation="horizontal" android:padding="@dimen/dp_20">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/app_name" android:src="@mipmap/ic_agreement" />
<TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="@dimen/dp_20" android:layout_weight="1" android:includeFontPadding="false" android:text="删除个人信息" android:textColor="@color/color_505258" android:textSize="@dimen/sp_14" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/app_name" android:src="@mipmap/ic_arrow_right" />
</LinearLayout>
<View android:layout_width="match_parent" android:layout_height="1dp" android:layout_marginStart="@dimen/dp_50" android:background="@color/color_F6F6F6" />
<LinearLayout android:id="@+id/ll2" android:layout_width="match_parent" android:layout_height="wrap_content" android:foreground="?android:attr/selectableItemBackground" android:gravity="center_vertical" android:orientation="horizontal" android:padding="@dimen/dp_20">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/app_name" android:src="@mipmap/ic_agreement" />
<TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="@dimen/dp_20" android:layout_weight="1" android:includeFontPadding="false" android:text="注销账户" android:textColor="@color/color_505258" android:textSize="@dimen/sp_14" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/app_name" android:src="@mipmap/ic_arrow_right" />
</LinearLayout>
<View android:layout_width="match_parent" android:layout_height="1dp" android:layout_marginStart="@dimen/dp_50" android:background="@color/color_F6F6F6" />
<LinearLayout android:id="@+id/ll3" android:layout_width="match_parent" android:layout_height="wrap_content" android:foreground="?android:attr/selectableItemBackground" android:gravity="center_vertical" android:orientation="horizontal" android:padding="@dimen/dp_20">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/app_name" android:src="@mipmap/ic_agreement" />
<TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="@dimen/dp_20" android:layout_weight="1" android:includeFontPadding="false" android:text="关于" android:textColor="@color/color_505258" android:textSize="@dimen/sp_14" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/app_name" android:src="@mipmap/ic_arrow_right" />
</LinearLayout>
</LinearLayout>
最外层 LinearLayout 的 background:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="10dp" /> <solid android:color="@color/white" /></shape>
可以看到嵌套虽然不深,但是已经拉的很长,不易阅读修改。
且 哪怕是一层的嵌套优化,也是优化,积少成多。
下部分
利用 TextView 的 drawableStart 和 drawableEnd 属性,来做简化,可以直接去掉左右两边的 ImageView。
至于分割线,利用 LinearLayout 的 divider 和 showDividers 属性,写个 shape,来做简化,去掉 item 之间做横线的 View。
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/dp_15" android:layout_marginVertical="@dimen/dp_20" android:background="@drawable/shape_bg_white" android:divider="@drawable/shape_divider_my" android:orientation="vertical" android:showDividers="middle">
<TextView android:id="@+id/tv_delete_user" android:layout_width="match_parent" android:layout_height="wrap_content" android:drawablePadding="@dimen/dp_16" android:foreground="?android:attr/selectableItemBackground" android:gravity="center_vertical" android:includeFontPadding="false" android:padding="@dimen/dp_20" android:text="删除个人信息" android:textColor="@color/color_505258" android:textSize="@dimen/sp_14" app:drawableEndCompat="@mipmap/ic_arrow_right" app:drawableStartCompat="@mipmap/ic_agreement" />
<TextView android:id="@+id/tv_logout_user" android:layout_width="match_parent" android:layout_height="wrap_content" android:drawablePadding="@dimen/dp_16" android:foreground="?android:attr/selectableItemBackground" android:gravity="center_vertical" android:includeFontPadding="false" android:padding="@dimen/dp_20" android:text="注销账户" android:textColor="@color/color_505258" android:textSize="@dimen/sp_14" app:drawableEndCompat="@mipmap/ic_arrow_right" app:drawableStartCompat="@mipmap/ic_agreement" />
<TextView android:id="@+id/tv_about" android:layout_width="match_parent" android:layout_height="wrap_content" android:drawablePadding="@dimen/dp_16" android:foreground="?android:attr/selectableItemBackground" android:gravity="center_vertical" android:includeFontPadding="false" android:padding="@dimen/dp_20" android:text="关于" android:textColor="@color/color_505258" android:textSize="@dimen/sp_14" app:drawableEndCompat="@mipmap/ic_arrow_right" app:drawableStartCompat="@mipmap/ic_agreement" />
</LinearLayout>
shape:
<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:left="@dimen/dp_50" > <shape android:shape="rectangle"> <solid android:color="@color/color_F6F6F6" /> <size android:height="1dp" /> </shape> </item></layer-list>
可以看到,层级减少了,行数也减少了,看起来清爽多了。
style 简化
尽管如此,我们还是有可以简化的空间。
TextView 有一些共同属性,可以抽取做一个 style。
<style name="MyTextView"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:drawablePadding">@dimen/dp_16</item> <item name="android:foreground">?android:attr/selectableItemBackground</item> <item name="android:gravity">center_vertical</item> <item name="android:includeFontPadding">false</item> <item name="android:padding">@dimen/dp_20</item> <item name="android:textColor">@color/color_505258</item> <item name="android:textSize">@dimen/sp_14</item> <item name="drawableEndCompat">@mipmap/ic_arrow_right</item> </style>
再看简化后的代码
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/dp_15" android:layout_marginVertical="@dimen/dp_20" android:background="@drawable/shape_bg_white" android:divider="@drawable/shape_divider_my" android:orientation="vertical" android:showDividers="middle">
<TextView android:id="@+id/tv_delete_user" style="@style/MyTextView" android:text="删除个人信息" app:drawableStartCompat="@mipmap/ic_agreement" />
<TextView android:id="@+id/tv_logout_user" style="@style/MyTextView" android:text="注销账户" app:drawableStartCompat="@mipmap/ic_agreement" />
<TextView android:id="@+id/tv_about" style="@style/MyTextView" android:text="关于" app:drawableStartCompat="@mipmap/ic_agreement" />
</LinearLayout>
更加精简了,只有简化前的一半,共同属性封装,只需要关注业务参数。
核心属性
LinearLayout
divider,分割线
showDividers,分割线的显示方式
layout_marginVertical,代替原来的 layout_marginTop、layout_marginBottom
layout_marginHorizontal,代替原来的 layout_marginStart、layout_marginEnd
题外话,LinearLayout 的 android:animateLayoutChanges="true",可以在其子 view 添加移除的时候添加简单的动画。
TextView
drawableEndCompat,即原来的 drawableEnd,设置右边的 drawable,其他方向同理
drawablePadding,drawable 与文字之前的内边距
includeFontPadding,TextView 默认 top 是有 6dp 的 padding 的,false 可去掉,小细节
foreground,添加这个属性会有水波纹的点击效果,省了写 selector
ok,到此结束,无聊的知识又增加了。
版权声明: 本文为 InfoQ 作者【yechaoa】的原创文章。
原文链接:【http://xie.infoq.cn/article/e479ffb1d83d9abc5e093d283】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
yechaoa
优质作者 2018.10.23 加入
知名互联网大厂技术专家,多平台博客专家、优秀博主、人气作者,博客风格深入浅出,专注于Android领域,同时探索于大前端方向,持续研究并落地前端、小程序、Flutter、Kotlin等相关热门技术










评论