Android ArrayAdapter的ListView布局优化:FrameLayout真的没用吗?

Android Layout optimization for ListView of ArrayAdapter: is FrameLayout really useless?

我已经为我的应用程序创建了一个颜色目录,并决定使用数组适配器来扩充这个目录。我的配色方案如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:layout_marginLeft="20dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:layout_marginRight="40dp"
        android:layout_marginEnd="40dp">

        <ImageView
            android:id="@+id/fav_swatch"
            android:layout_width="80dp"
            android:layout_height="match_parent"/>

        <TextView
            android:id="@+id/fav_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/fav_swatch"
            android:layout_toEndOf="@+id/fav_swatch"
            android:paddingLeft="30dp"
            android:paddingStart="30dp"
            android:paddingTop="10dp"
            android:textSize="20sp"
            />

        <TextView
            android:id="@+id/fav_coord"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/fav_swatch"
            android:layout_toEndOf="@+id/fav_swatch"
            android:layout_below="@+id/fav_name"
            android:paddingLeft="30dp"
            android:paddingStart="30dp"
            android:paddingTop="10dp"
            android:textSize="20sp"
            />

        <ImageButton
            android:id="@+id/btn_delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_marginLeft="10dp"
            android:background="@drawable/ic_clear"/>

        <ImageButton
            android:id="@+id/btn_modify"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/btn_delete"
            android:layout_toStartOf="@+id/btn_delete"
            android:background="@drawable/ic_edit"/>

    </RelativeLayout>

</FrameLayout>

我的activity布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fav_fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin" />

    <ListView
        android:id="@+id/fav_lv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

    </ListView>

</FrameLayout>

所以这段代码导致所需的布局如下:

问题是 Android 警告我

This RelativeLayout or its parent FrameLayout is useless

它并不是真的没用,因为如果我只保留 RelativeLayout 作为父级:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:layout_marginLeft="20dp"
    android:layout_marginStart="20dp"
    android:layout_marginTop="20dp"
    android:layout_marginBottom="20dp"
    android:layout_marginRight="40dp"
    android:layout_marginEnd="40dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

        <ImageView
            android:id="@+id/fav_swatch"
            android:layout_width="80dp"
            android:layout_height="match_parent"/>

        <TextView
            android:id="@+id/fav_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/fav_swatch"
            android:layout_toEndOf="@+id/fav_swatch"
            android:paddingLeft="30dp"
            android:paddingStart="30dp"
            android:paddingTop="10dp"
            android:textSize="20sp"
            />

        <TextView
            android:id="@+id/fav_coord"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/fav_swatch"
            android:layout_toEndOf="@+id/fav_swatch"
            android:layout_below="@+id/fav_name"
            android:paddingLeft="30dp"
            android:paddingStart="30dp"
            android:paddingTop="10dp"
            android:textSize="20sp"
            />

        <ImageButton
            android:id="@+id/btn_delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_marginLeft="10dp"
            android:background="@drawable/ic_clear"/>

        <ImageButton
            android:id="@+id/btn_modify"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/btn_delete"
            android:layout_toStartOf="@+id/btn_delete"
            android:background="@drawable/ic_edit"/>

</RelativeLayout>

边距被忽略了,我得到了这种丑陋的布局:

我的问题是:有没有什么方法可以在不放置 'useless' FrameLayout 的情况下获得正确的布局以获得更清晰和更优化的代码?

编辑:有趣的 java 代码:

// Construct the data source
        ArrayList<Colour> arrayOfColours = new ArrayList<>();

        final ColourAdapter adapter = new ColourAdapter(this, arrayOfColours);

        ListView lv = (ListView) findViewById(R.id.fav_lv);
        lv.setAdapter(adapter);

        final Colour[] colour = new Colour[ca.getMaxNumberOfFavColours()];
        for (int i = 0; i < numberOfColours; i++) {
            colour[i] = new Colour(colourPixel[i], colourName[i]);
            adapter.add(colour[i]);
        }

在您的场景中 FrameLayout 包含一个子元素 RelativeLayout。您的所有其他元素都包含在 RelativeLayout 中。可能这就是原因 Android Studio 向您发出警告。

This RelativeLayout or its parent FrameLayout is useless.

我不明白你把 RelativeLayout 放在 FrameLayout 里面的意思。相反,我还建议使用其中之一。

此外,在第二种情况下,您只需执行此操作即可获得相同的结果...

  1. 正在删除 RelativeLayout 的边距。
  2. RelativLayout 中添加 android:padding="20dp" 而不是边距。

如果您对此有任何疑问,请告诉我。

我建议您 see the diff. in margin and padding 并避免为布局的最外层容器留出边距。

PS: 开发人员不会过多关注警告,直到它们变成错误。 :p