如何在添加项目时使GridView适应其高度

Tim*_*res 27 android gridview

我试图在GridView中显示一个动态增长的字符串列表,其中包含一个复选框,GridView本身位于TableLayout中.

我可以连续显示这些"已复选"的字符串.当我让用户在GridView中动态添加新字符串时,我的问题出现了.

我创建了一个接收字符串列表的自定义适配器.假设我们有n个字符串.适配器为项目计数返回'n + 1'; 在getView中,它返回:

  • 一个带有LinearLayout的视图,它本身有前两个项目的CheckBox和EditText,
  • 带有简单按钮的LinearLayout,带有'+'标题的'n + 1'项.

到现在为止还挺好.单击"+"按钮时,我将一个空字符串添加到字符串列表中,并在适配器中调用notifyDataSetChanged.

GridView重新绘制了一个项目.但它保持原始高度并创建一个垂直滚动条.我希望GridView扩展它的高度(即在屏幕上占用更多空间并显示所有项目).

我试图将屏幕更改为垂直LinearLayout而不是TableLayout,但结果是相同的.

这是我的屏幕布局:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="none">
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    >

    <!-- other lines omitted -->

    <LinearLayout android:layout_width="fill_parent" 
                  android:layout_height="wrap_content" >
        <TextView
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:text="@string/wine_rack_explanation"
            android:layout_gravity="center_vertical" />
          <GridView
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content"
            android:id="@+id/gvRack"
            android:columnWidth="90dp"    
            android:numColumns="auto_fit" />
    </LinearLayout>

<!-- other lines omitted -->

</LinearLayout>
</ScrollView>
Run Code Online (Sandbox Code Playgroud)

适配器中的复选框+字符串项定义如下:

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"

  android:layout_width="wrap_content"
  android:layout_height="wrap_content">
    <CheckBox android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:id="@+id/cbCoordinate"
              android:checked="true"
              />
    <EditText android:id="@+id/txtCoordinate"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

"+"按钮项定义如下:

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">

    <Button android:id="@+id/btnAddBottle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/add_bottle_caption" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

在添加项目后,我试图在GridView上调用invalidate或invalideViews.在TableLayout和TableRow上也称为invalidate(在屏幕的先前布局中).没有成功.

知道为什么GridView拒绝扩展它的高度?

(请注意,我完全可以使用除GridView之外的其他视图组)

Raj*_*008 52

使用此代码

public class MyGridView  extends GridView {

    public MyGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    public MyGridView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这很好用,但是当我添加很多项目时,我现在在GridView的底部找到一个大的空白区域.我无法将此空间用于任何其他原因,因为我已经使用Developer Option的Show Layout Outlines Feature进行了检查.请帮忙. (4认同)

Hir*_*tel 8

我这样做了:

此代码将根据Child的数量设置GridView高度.

注意:5列数在哪里.

private void setDynamicHeight(GridView gridView) {
        ListAdapter gridViewAdapter = gridView.getAdapter();
        if (gridViewAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        int items = gridViewAdapter.getCount();
        int rows = 0;

        View listItem = gridViewAdapter.getView(0, null, gridView);
        listItem.measure(0, 0);
        totalHeight = listItem.getMeasuredHeight();

        float x = 1;
        if( items > 5 ){
            x = items/5;
            rows = (int) (x + 1);
            totalHeight *= rows;
        }

        ViewGroup.LayoutParams params = gridView.getLayoutParams();
        params.height = totalHeight;
        gridView.setLayoutParams(params);
    }
Run Code Online (Sandbox Code Playgroud)

希望这会帮助你.


Uts*_*wal 5

根据/sf/users/296323821/分享的想法开发,谢谢:)

通过此函数向您传递 GridView 及其列数,您就完成了。

private void setGridViewHeightBasedOnChildren(GridView gridView, int noOfColumns) {
        ListAdapter gridViewAdapter = gridView.getAdapter();
        if (gridViewAdapter == null) {
            // adapter is not set yet
            return;
        }

        int totalHeight; //total height to set on grid view
        int items = gridViewAdapter.getCount(); //no. of items in the grid
        int rows; //no. of rows in grid

        View listItem = gridViewAdapter.getView(0, null, gridView);
        listItem.measure(0, 0);
        totalHeight = listItem.getMeasuredHeight();

        float x;
        if( items > noOfColumns ){
            x = items/noOfColumns;

            //Check if exact no. of rows of rows are available, if not adding 1 extra row
            if(items%noOfColumns != 0) {
                rows = (int) (x + 1);
            }else {
                rows = (int) (x);
            }
            totalHeight *= rows;

            //Adding any vertical space set on grid view
            totalHeight += gridView.getVerticalSpacing() * rows;
        }

        //Setting height on grid view
        ViewGroup.LayoutParams params = gridView.getLayoutParams();
        params.height = totalHeight;
        gridView.setLayoutParams(params);
    }
Run Code Online (Sandbox Code Playgroud)


Gra*_*ham 4

当为 GridView 调用 onMeasure() 时,如果 heightMode 为 MeasureSpec.UNSPECIFIED,则 gridview 将与它包含的所有元素一样高(加上一些填充)。

为了确保这种情况,您可以创建一个扩展 GridView 的快速自定义视图并包含以下覆盖:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, MeasureSpec.UNSPECIFIED);
    }
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。当单元格的内容动态更改时,您是否尝试过此操作?我已经重写了我的代码以摆脱 GridView,因此无法测试您的答案。 (2认同)