Gridview高度被削减

tac*_*one 120 android gridview

我正在尝试在gridview中显示8个项目.遗憾的是,gridview高度总是太小,所以它只显示第一行,而第二行的一小部分.

设置android:layout_height="300dp"使它工作.包装content,fill_parent显然不是.

我的网格视图:

<GridView
    android:id="@+id/myId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:horizontalSpacing="2dp"
    android:isScrollContainer="false"
    android:numColumns="4"
    android:stretchMode="columnWidth"
    android:verticalSpacing="20dp" />
Run Code Online (Sandbox Code Playgroud)

我的物品资源:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:minHeight="?android:attr/listPreferredItemHeight" >

    <ImageView
        android:id="@+id/appItemIcon"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_dialog_info"
        android:scaleType="center" />      

    <TextView
        android:id="@+id/appItemText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="My long application name"
        android:gravity="center_horizontal"
        android:textAppearance="?android:attr/textAppearanceSmall" />

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

这个问题似乎与缺乏垂直空间有关.

我能做什么 ?

tac*_*one 342

经过(太多)研究,我偶然发现了Neil Traft的优秀答案.

适应他的工作GridView已经很容易.

ExpandableHeightGridView.java:

package com.example;
public class ExpandableHeightGridView extends GridView
{

    boolean expanded = false;

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

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

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

    public boolean isExpanded()
    {
        return expanded;
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // HACK! TAKE THAT ANDROID!
        if (isExpanded())
        {
            // Calculate entire height by providing a very large height hint.
            // View.MEASURED_SIZE_MASK represents the largest height possible.
            int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
                    MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);

            ViewGroup.LayoutParams params = getLayoutParams();
            params.height = getMeasuredHeight();
        }
        else
        {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    public void setExpanded(boolean expanded)
    {
        this.expanded = expanded;
    }
}
Run Code Online (Sandbox Code Playgroud)

将它包含在您的布局中,如下所示:

<com.example.ExpandableHeightGridView
    android:id="@+id/myId"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:horizontalSpacing="2dp"
    android:isScrollContainer="false"
    android:numColumns="4"
    android:stretchMode="columnWidth"
    android:verticalSpacing="20dp" />
Run Code Online (Sandbox Code Playgroud)

最后你只需要让它扩展:

mAppsGrid = (ExpandableHeightGridView) findViewById(R.id.myId);
mAppsGrid.setExpanded(true);
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案不具有内存效率,如果单元格是图像,应用程序将崩溃.这个解决方案告诉scrollview什么是完整gridview的高度,所以它可以下降,但问题是这样做它渲染一切而不使用回收.不超过200件物品可以使用. (20认同)
  • @adamp如果这不​​好,请使用您能想到的最佳解决方案添加您的答案 (11认同)
  • @adamp我认为有这方面的有用案例.如果您在二维数组中显示的项目数量有限,那么使用这种GridView似乎比尝试创建某种自定义/动态TableLayout更容易,不是吗? (7认同)
  • 对我不起作用,我在ScrollView下放置了ExpandableHeightGridView,它切断了最后一个视图. (5认同)
  • @tacone有很多更好的解决方案可以解决这个问题,它可以在Web框架,支持库和其他开源代码中轻松获得,其中最简单的可以是简单的for循环从适配器或其他地方提取视图.将它们添加到GridLayout(不是GridView; GridLayout也可以在支持lib中使用)TableLayout或类似的. (3认同)
  • @adamp所以如果我有一个按预期工作的"普通"GridView,我想在另一个Activity的ScrollView中显示这些项目(前6项)的"预览",并带有一个"查看全部"按钮,启动"普通的"GridView,那么你的建议是使用能够复制*完全*我在GridView中已经完成的工作的表来创建一个全新的UI?还是我误解了你? (2认同)
  • @tacone这很棒.但现在的问题是我的'GridView'已经在扩展,但它仍然在最后一行被削减.'expandSpec'的计算是否简短? (2认同)
  • @chakrit你说你不能以正确的方式做事,但这只意味着你会在这一点上从错误,边缘情况和性能问题中付出代价.立即付款或稍后付款.:) (2认同)
  • 如果网格视图具有多个单元格布局,这将不起作用。 (2认同)

Jac*_*b R 32

在使用@tacone的答案并确保它有效后,我决定尝试缩短代码.这是我的结果.PS:它相当于将tacones中的布尔"扩展"应答始终设置为true.

public class StaticGridView extends GridView {

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

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

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

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST));
        getLayoutParams().height = getMeasuredHeight();
    }
}
Run Code Online (Sandbox Code Playgroud)


Pel*_*nes 5

另一个对我有用的类似方法是计算一行的高度,然后使用静态数据(您可以将其调整为paginate),您可以计算您拥有的行数并轻松调整GridView高度.

    private void resizeGridView(GridView gridView, int items, int columns) {
    ViewGroup.LayoutParams params = gridView.getLayoutParams();
    int oneRowHeight = gridView.getHeight();
    int rows = (int) (items / columns);
    params.height = oneRowHeight * rows;
    gridView.setLayoutParams(params);
}
Run Code Online (Sandbox Code Playgroud)

设置适配器后以及绘制GridView时使用此代码,或者您将获得height = 0.

gridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (!gridViewResized) {
                    gridViewResized = true;
                    resizeGridView(gridView, numItems, numColumns);
                }
            }
        });
Run Code Online (Sandbox Code Playgroud)


spa*_*ter 5

发现 tacones 的回答很有帮助...所以我将它移植到 C# (Xamarin)

public class ExpandableHeightGridView: GridView
{
    bool _isExpanded = false;

    public ExpandableHeightGridView(Context context) : base(context)
    {            
    }

    public ExpandableHeightGridView(Context context, IAttributeSet attrs) : base(context, attrs)
    {            
    }

    public ExpandableHeightGridView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
    {            
    }

    public bool IsExpanded
    {
        get { return _isExpanded; }

        set { _isExpanded = value;  }
    }

    protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // HACK! TAKE THAT ANDROID!
        if (IsExpanded)
        {
            // Calculate entire height by providing a very large height hint.
            // View.MEASURED_SIZE_MASK represents the largest height possible.
            int expandSpec = MeasureSpec.MakeMeasureSpec( View.MeasuredSizeMask, MeasureSpecMode.AtMost);
            base.OnMeasure(widthMeasureSpec,expandSpec);                

            var layoutParameters = this.LayoutParameters;
            layoutParameters.Height = this.MeasuredHeight;
        }
        else
        {
            base.OnMeasure(widthMeasureSpec,heightMeasureSpec);    
        }
    }
}
Run Code Online (Sandbox Code Playgroud)