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

时间:2022-05-10 14:49:26

I am trying to display a dynamically-growing list of strings with a checkbox in a GridView, which is itself in a TableLayout.

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

I can display these "checkboxed" strings fine in a row. My problem occurs when I let the user dynamically add new strings in the GridView.

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

I created a custom adapter that receives the list of strings. Say we have n strings. The adapter returns 'n + 1' for the items count; in getView, it returns:

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

  • a View with a LinearLayout, itself having a CheckBox and an EditText for the first n items,
  • 一个带有LinearLayout的视图,它本身有前两个项目的CheckBox和EditText,

  • a LinearLayout with a simple button, with a '+' caption for the 'n + 1'th item.
  • 带有简单按钮的LinearLayout,带有'+'标题的'n + 1'项。

So far so good. When the '+' button is clicked, I add an empty string to the list of strings and call notifyDataSetChanged in the adapter.

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

The GridView redraws itself with one more item. BUT it keeps its original height and creates a vertical scrollbar. I'd like the GridView to expand its height (i.e. take up more space on screen and show all items).

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

I've tried to change the screen to a vertical LinearLayout instead of a TableLayout, but the results is the same.

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

Here is the layout of my screen:

这是我的屏幕布局:

<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>

The checkbox + string item from the adapter is defined like this:

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

<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>

The '+' button item is defined like this:

“+”按钮项定义如下:

<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>

I've tried to call invalidate or invalideViews on the GridView after an item is added. Also called invalidate on the TableLayout and TableRow (in the previous layout of the screen). No success.

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

Any idea why the GridView refuses to extend its height ?

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

(Note that I am completely open to using an other viewgroup than the GridView)

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

5 个解决方案

#1


49  

Use this code

使用此代码

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);
    }
}

#2


8  

I have done this way:

我这样做了:

This code will set GridView height as per number of Child.

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

Note: Where 5 is number of columns.

注意:其中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);
    }

Hope this will help you.

希望这会帮助你。

#3


4  

When onMeasure() is called for GridView, if heightMode is MeasureSpec.UNSPECIFIED, then the gridview will be as tall as all of it's contained elements (plus some padding).

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

To ensure that this is the case, you can make a quick custom view extending GridView and including the following override:

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, MeasureSpec.UNSPECIFIED);
    }

#4


4  

This is working for me:

这对我有用:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background" >

        <!-- MORE LAYOUTS IF YOU WANT -->

    <ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:fillViewport="true" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

                <!-- MORE LAYOUTS IF YOU WANT -->

       <GridView
            android:id="@+id/gridview"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="5dp"
            android:gravity="center"
            android:horizontalSpacing="10dp"
            android:numColumns="auto_fit"
            android:stretchMode="columnWidth"
            android:verticalSpacing="10dp" >
       </GridView>

             <!-- MORE LAYOUTS IF YOU WANT -->

    </RelativeLayout>

    </ScrollView>

</RelativeLayout>

#5


1  

Graham's solution did not work for me. However this one (with a bit more hacking) did: https://*.com/a/8483078/479478

格雷厄姆的解决方案对我不起作用。然而,这个(更多的黑客攻击)做了:https://*.com/a/8483078/479478

#1


49  

Use this code

使用此代码

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);
    }
}

#2


8  

I have done this way:

我这样做了:

This code will set GridView height as per number of Child.

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

Note: Where 5 is number of columns.

注意:其中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);
    }

Hope this will help you.

希望这会帮助你。

#3


4  

When onMeasure() is called for GridView, if heightMode is MeasureSpec.UNSPECIFIED, then the gridview will be as tall as all of it's contained elements (plus some padding).

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

To ensure that this is the case, you can make a quick custom view extending GridView and including the following override:

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, MeasureSpec.UNSPECIFIED);
    }

#4


4  

This is working for me:

这对我有用:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background" >

        <!-- MORE LAYOUTS IF YOU WANT -->

    <ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:fillViewport="true" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

                <!-- MORE LAYOUTS IF YOU WANT -->

       <GridView
            android:id="@+id/gridview"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="5dp"
            android:gravity="center"
            android:horizontalSpacing="10dp"
            android:numColumns="auto_fit"
            android:stretchMode="columnWidth"
            android:verticalSpacing="10dp" >
       </GridView>

             <!-- MORE LAYOUTS IF YOU WANT -->

    </RelativeLayout>

    </ScrollView>

</RelativeLayout>

#5


1  

Graham's solution did not work for me. However this one (with a bit more hacking) did: https://*.com/a/8483078/479478

格雷厄姆的解决方案对我不起作用。然而,这个(更多的黑客攻击)做了:https://*.com/a/8483078/479478