在安卓中如何让子视图与父视图匹配(match_parent)?

3

我有一个简单的线性布局,我在适配器中进行填充:

    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.category_listview_row, parent, false);
        } else {
            ((LinearLayout)convertView).removeAllViews();
        }

        if (LAYOUT_TYPES.GRID.equals(layoutType)) {
            convertView = CategoryFragment.getViewForGridLayout(context, displayArray, position, convertView, listener);
        } else {
            convertView = CategoryFragment.getViewForListLayout(context, displayArray, position, convertView, listener);
        }

        return convertView;
    }

在这里,category_listview_row 是以下内容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:gravity="top"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
getViewForGridLayout 方法通过编程方式创建一个或多个视图,并将它们添加到 convertView 中。
我希望所有子视图的高度都与父视图匹配,但是我无法实现这一点。这是通过编程方式添加的子视图的外部线性布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/base_listview_style_one_layout"
    android:orientation="horizontal"
    android:padding="@dimen/node_default_spacing"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:background="#5ab9c6">

这个布局有子视图,根据要显示的实际数据进行删除,所以有些子视图比其他的长。但是我希望它们都能与父视图一样高,这样看起来就不会奇怪。
这是我看到的屏幕截图:
- 第一行没问题,因为两个项目都有标题和副文本。 - 在第二行中,第二个项目没有副文本,所以该视图较小。然而,我希望它占据整个行的高度,这样单行中的所有项目都具有相同的高度。

enter image description here

任何提示?谢谢!

然而我无法让这个运行起来--你看到了什么?实际上哪些视图高度不正确?当您使用 Android Studio 的布局检查器来检查这些内容时,它会显示给您什么?“这是通过编程方式添加的子视图的外线性布局”--您的背景色是否具有正确的高度? - CommonsWare
@CommonsWare 我已经添加了一张截图来更好地描述我所看到的情况。谢谢。 - zundi
2
如果您使用实际设置来实现网格(例如,RecyclerViewGridLayoutManager),则可能会更容易,而不是尝试使用LinearLayout来模拟。否则,我建议使用Android Studio的LayoutInspector来确定为什么您的规则没有按照您的预期工作。 - CommonsWare
如果我没记错的话,我曾尝试使用RecyclerViewGridLayoutManager,但是让一些行有2个项目,而其他行只有1个项目(并且填满整行)并不直观。我会重新阅读GridLayoutManager文档。 - zundi
但是能够让某些行有2个项目,其他行有1个项目(并且填满整行),这并不简单。将 SpanSizeLookup 附加到 GridLayoutManager 上,在其中提供 getSpanSize() 方法来指示给定位置要跨越的单元格数量。然后你就完成了。我的书的 RecyclerView 章节中有关于此的介绍,并提供了一个名为 VideoTable 的示例应用程序来演示其使用方法。 - CommonsWare
显示剩余3条评论
8个回答

3

我建议使用GridLayoutManager的Recyclerview。

如果您想要某些项目跨越多列,可以通过在GridLayoutManager上设置SpanSizeLookup来实现。

这里有一个简单的示例https://dev59.com/KV8d5IYBdhLWcg3wYxg-#26907508


1
很可能您的布局参数被忽略了。请确保像这样将子视图添加到您的convertView中:
View view = inflater.inflate( R.layout.item /* resource id */,
                                     convertView /* parent */,
                                     true /*attachToRoot, you dont need to call addView then*/);

1

不要移除TextView,为什么不只是将其设置为不可见或将其颜色设置为白色以占据空间呢?


如果两张卡片都没有副文本怎么办?那将会有不必要的空白。 - RadekJ

1
请将您的LinearLayout高度从"wrap_content"更改为"match_parent"。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:gravity="top"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />`

0

@zundi 如果你用RecyclerView和LayoutManager的正确方式,会极大地简化你的生活,但是如果有一点学习曲线不适合你,这里还有一个选项没有被提到:

你可以在包含子文本的TextView上定义android:lines=x。

只是使用match_parent对你来说行不通,因为你想要LinearLayout包裹其子元素的高度,并且其子元素匹配父元素,这是一个循环依赖关系。


0

这个方法可以在你使用的线性布局或文本视图上执行

你已经设置了

android:layout_height="match_parent"

但没有设置高度,所以这是一个简单的情况

android:layout_height="match_parent"

因此,即使字符串中没有值,它仍将包含分配给它的高度


0
  1. 将父布局的高度设置为wrap_content。
  2. 将子视图的高度设置为match-parent。

请尝试这样做,希望它可以解决您的问题。


0
@zundi,你可以使用视图持有者设计模式与回收视图适配器,并定义哪一行需要两个图像,哪一行需要一个。这比使用线性布局要简单得多。 Recycleview show different view types有一个相当不错的解释,说明如何做到这一点。
另外,回答你关于制作“一些带有2个项目的行和其他带有1个项目的行”的问题,你可以使用GridLayoutManager.SpanSizeLookup spanSizeLookup的setSpanSizeLookup(GridLayoutManager.SpanSizeLookup spanSizeLookup)方法,并在活动中定义它。 RecycleView's span size提供了更多关于如何实现这一点的信息。
mLayoutManager.setSpanSizeLookUp(new GridLayoutManager.SpanSizeLookUp() {
     @Override
     public int getSpanSize(int position) {
         if(position == 0) 
            return 2; //here the view takes up two spaces in a row(header)
         else return 1; //here view takes 1 space i.e., 2 views in a total row
    } });

在上面的例子中,我的网格布局管理器根据不同的位置使用2个视图持有者,并决定其是否为标题并填充数据。
其他解决方案:
与其在布局中使用match_parent和wrap_content,不如为高度给一个固定的“dp”。这样应该使视图看起来更一致。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接