Android 硬布局item的高级写法

2022-06-10 14:47:22 浏览数 (1)

效果:

这种布局应该是非常常见了,且写的比较多。

今天简单探讨一下效果图中上下两种布局的写法。

比较

上下效果一致

行数

层级

上部分

121

3

下部分

55

2

下部分继续精简

28

2

可以看出,对比还是很明显的,精简到最后只有最开始的四分之一。

上部分

先看常规item写法,横向的LinearLayout嵌套三个子View,分别是

  • 左边的ImageView,
  • 中间的TextView,
  • 和右边的ImageView。

然后每个横向的LinearLayout之间添加一个高度1dp的View来作为横线。

代码语言:javascript复制
    <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:

代码语言:javascript复制
<?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。

代码语言:javascript复制
    <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:

代码语言:javascript复制
<?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。

代码语言:javascript复制
    <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>

再看简化后的代码

代码语言:javascript复制
    <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,到此结束,无聊的知识又增加了。

0 人点赞