网格布局列宽

54
我在我的GridLayout中有两列。我想做的是让这两列每个占据屏幕宽度的一半,然后让它们的子内容填充自己的单元格宽度/高度。我尝试将子项设置为fill_parent,但这只会导致第一个子项接管整个布局。而且似乎GridLayout不支持weight?也许有更好的布局可用,但我想要一个网格样式的布局,这似乎是自然的选择。

1
你是想填充特定的高度/宽度吗?并且你希望所有网格项的高度都相同吗? - se_bastiaan
2
是的。我有两列。我希望它们的宽度为屏幕宽度的50%,因此它们在一起将等于屏幕的宽度。然后它们的高度与像素宽度相同。所以它们将是正方形的。 - bwoogie
你找到了解决方案吗?如果是的话,请分享一下。我也想要同样的功能。 - BSKANIA
6个回答

71

这段代码在API21之前可通过支持库使用!

我有一段简单的代码,可以在GridLayout中展示4个按钮,每列占用50%的可用空间,希望它能够帮到你。

<GridLayout
    android:id="@+id/grid"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="2"
    >


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        android:layout_gravity="fill"
        android:layout_columnWeight="1"
        />

       <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        android:layout_gravity="fill"
        android:layout_columnWeight="1"
        />

       <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        android:layout_gravity="fill"
        android:layout_columnWeight="1"
        />

       <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        android:layout_gravity="fill"
        android:layout_columnWeight="1"
        />



</GridLayout>

解决方案或许是这样的:

android:layout_gravity="fill"
android:layout_columnWeight="1"

20
现在可以使用支持库的最新版本,在API 21之前的设备上使用GridLayout了。只需添加依赖项 - com.android.support:gridlayout-v7:22.0.0即可。 - oznus
1
@oznus 我试过了,仍然无效。它不接受 weight 属性。 - Nigam Patro
在使用新的 GridLayout 时,应该使用 app 命名空间,因此应该是 app:layout_gravity="fill" - r3flss ExlUtr
7
根据我的经验,如果要让权重正常工作,您需要将 "layot_width" 设置为 "0dp"。@NigamPatro希望这可以帮助。 - netimen
1
提醒一下,因为这个问题让我花费了很长时间去解决。如果你正在开发 API 28 或更高版本的应用程序,那么有一个名为 AndroidX 的新支持库可供使用。如果在 gradle.properties 文件中设置了 android.useAndroidX 为 true,则旧的支持库将无法正常工作。对于某些原因,这也是我的情况。但是,你只需要使用 androidx.gridlayout.widget.GridLayout 而不是 android.support.v7.widget.GridLayout 就可以解决问题了。 - DerDerrr
这很棒。另外,如果您有多行要相同,请记得使用 android:layout_rowWeight="1" - Rob Rouse Jr.

16

对于 API 21 之前的版本,请使用支持库:

添加

compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'

添加到你的依赖项中。

然后在你的xml文件中:

<android.support.v7.widget.GridLayout
                    xmlns:app="http://schemas.android.com/apk/res-auto"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:columnCount="2"
                    app:orientation="horizontal"
                    app:rowCount="1">

                    <TextView
                        android:text="1"
                        android:textStyle="bold"
                        app:layout_columnWeight="1"
                        />

                    <TextView
                        android:text="2"
                        android:textStyle="bold"
                        app:layout_columnWeight="1" />

</android.support.v7.widget.GridLayout>

请注意使用“app”前缀,并不要忘记添加

xmlns:app="http://schemas.android.com/apk/res-auto"

到您的XML文件


11

在网格布局中动态添加视图,该布局有2列,每列占可用空间的50%:

GridLayout gridLayout = new GridLayout();

View view; //it can be any view

GridLayout.LayoutParams param = new GridLayout.LayoutParams();

param.columnSpec = GridLayout.spec(GridLayout.UNDEFINED,GridLayout.FILL,1f);

param.width = 0;

view.setLayoutParams(param);

gridLayout.add(view);

以静态方式(在 .xml 文件中)。

<android.support.v7.widget.GridLayout
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:alignmentMode="alignBounds"
   app:columnCount="2"
   app:columnOrderPreserved="false"
   app:orientation="horizontal"
   android:layout_margin="20dp"
   android:layout_marginBottom="30dp"
   android:padding="4dp"
   app:rowCount="2">

<TextView
    android:layout_marginTop="2dp"
    android:id="@+id/edit_profile_username"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_column="0"
    app:layout_row="0"
    app:layout_gravity="fill"
    app:layout_columnWeight="1"
    android:text="@string/user_name" />

<TextView
    android:layout_marginTop="2dp"
    android:id="@+id/edit_profile_first_name"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_column="1"
    app:layout_row="0"
    app:layout_gravity="fill"
    app:layout_columnWeight="1"
    android:text="@string/first_name" />

<TextView
    android:layout_marginTop="2dp"
    android:id="@+id/edit_profile_middle_name"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_column="0"
    app:layout_gravity="fill"
    app:layout_columnWeight="1"
    app:layout_row="1"
    android:text="@string/middle_name" />

<TextView
    android:layout_marginTop="2dp"
    android:id="@+id/edit_profile_last_name" 
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_column="1"
    app:layout_gravity="fill"
    app:layout_columnWeight="1"
    app:layout_row="1"
    android:text="@string/last_name" />

</android.support.v7.widget.GridLayout>

非常好用!还有一个layout_rowWeight可以与layout_height="0dp"结合使用。 - FrankKrumnow
编程部分对我来说是有效的。 - SK. Fuad
有了编程解决方案,我该如何使其保持在特定高度的限制范围内?而不是占据整个屏幕。 - HUSSENI ABDULHAKEEM

5

好的,我放弃了网格视图,改用一些线性布局。我创建了一个垂直的布局,然后添加了两个水平的布局。这比网格视图稍微复杂一些...但至少在我想通之前它能够正常工作。

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical" >

        <ImageButton
            android:id="@+id/btn_mybutton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:background="@color/pomegranate"
            android:contentDescription="@string/contentDescriptionmybutton"
            android:src="@drawable/ic_launcher" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical" >

        <ImageButton
            android:id="@+id/btn_prefs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:background="@color/pomegranate"
            android:contentDescription="@string/contentDescriptionSettings"
            android:src="@drawable/ic_settings" />

    </LinearLayout>

</LinearLayout>

然后我添加了以下内容使按钮变成正方形 :)
@Override
 public void onWindowFocusChanged(boolean hasFocus) {
  super.onWindowFocusChanged(hasFocus);

  btnPrefs.setMinimumHeight(btnPrefs.getWidth());
  btnVerse.setMinimumHeight(btnMyButton.getWidth());

 }

我想让我的按钮高度与宽度相等,所以我使用了你提供的代码。它确实起作用,但我不明白为什么在一个 ActivityonCreate 中没有效果。有什么想法吗? - MikkoP

0
当您使用GridLayoutManager时,可以使用setSpanSizeLookup。以下是我的项目中的代码片段,应该能够帮助您正确地使用此方法:
if (mAdapter == null) {
    final int columnCount = getResources().getInteger(R.integer.numberGridColumns);
    mLayoutManager = new GridLayoutManager(getActivity(), columnCount);
    mLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            switch (mAdapter.getItemViewType(position)) {
                case ListAdapter.VIEW_TYPE_ONE_COLUMN:
                    return columnCount;
                case RecipeListAdapter.VIEW_TYPE_FULL_COLUMN:
                default:
                    return 1;
            }
        }
    });
    mRecyclerView.setLayoutManager(mLayoutManager);

    mAdapter = new RecipeListAdapter(mPresenter);
    mRecyclerView.setAdapter(mAdapter);
}
mAdapter.notifyDataSetChanged();

0
你可以扩展RelativeLayout类(或者使用LinearLayout)来确保项目的高度与高度相同。
public class GridItem extends RelativeLayout {

        public GridItem(Context context) {
                super(context);
        }

        public GridItem(Context context, AttributeSet attr) {
                super(context, attr);
        }

        public GridItem(Context context, AttributeSet attr, int integer) {
                super(context, attr, integer);
        }

        // Override onMeasure to give the view the same height as the specified width
        @Override
        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, widthMeasureSpec);
            setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
        }

}

项目布局的父视图应该是GridItem视图,以确保其正常工作。这必须是您在ListAdapter的getView中填充的布局文件。

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

    <!-- The content of the item -->

</my.packagename.GridItem>

将 GridView 的 stretchMode 设置为 columnWidth。这将使所有项目适合指定列数的宽度。新视图将确保它们也具有相同的高度。

<GridView
    android:id="@+id/gridList"
    android:numColumns="2"
    android:stretchMode="columnWidth"
/>

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