2010-09-10 53 views
4

我在一个ScrollView里面的一个LinearLayout里面有一个GridView,它可以从服务器中获取数据。在GridView下面是一个加载更多数据的按钮。我的GridView将有一个比屏幕更大的终极高度。如果我将GridView的高度设置为wrap_content或parent_fill,它将自己调整为确切的可用屏幕高度,并且根本不滚动,裁剪出多余的行。如果我明确地将layout_height设置为1000dip之类的东西,滚动行为会正确,但我无法预测我的滚动视图apriori的最终高度。如何计算Android上的ScrollView内的GridView所需的高度?

如何以编程方式确定GridView获得所需行为所需的高度?

这是我的布局如下。正如你可以看到我设置的高度1000dip,但毕竟是假的,我需要的价值得到自动设置/编程:

 <ScrollView 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:fillViewport="true"   
    android:layout_weight="1"  
    > 
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical"  
      > 

      <GridView xmlns:android="http://schemas.android.com/apk/res/android" 
       android:id="@+id/grid" 
       android:layout_width="fill_parent" 
       android:layout_height="1000dip" 
       android:columnWidth="70dp" 
       android:numColumns="auto_fit" 
       android:verticalSpacing="0dp" 
       android:horizontalSpacing="0dp" 
       android:stretchMode="columnWidth" 
       android:gravity="center" 
       android:background="#000000" 
       android:layout_weight="1" 
      /> 
      <Button 
      android:id="@+id/load_more" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:text="Load More Foo" 
      /> 
     </LinearLayout> 
    </ScrollView> 

回答

1

显然GridView的内部ScrollViews不是Android的土地洁净。用定制行切换到ListView。这似乎表现得更好。

+0

仅供参考我确实使用ListView编写了我自己定制的类似GridView的UI小部件,它工作得很好。 – esilver 2012-01-02 22:37:14

14

如果有人需要,可以采取以下一种方法。有点破解,但伎俩。你必须设置的GridView最初足够大,对于所有的视图(例如10000dip)

final GridView imageContainer = // your GridView 
imageContainer.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
      { 
      @Override 
      public void onGlobalLayout() 
       { 
       imageContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
       View lastChild = imageContainer.getChildAt(imageContainer.getChildCount() - 1); 
       imageContainer.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, lastChild.getBottom())); 
       } 
      }); 
+0

令人惊叹的黑客!有用。 – deviant 2012-08-19 09:47:11

+0

什么黑客兄弟!!!!! ...杰出... – 2012-09-11 06:19:03

2

我知道这是一个古老的情况下,但我也有类似的问题,在我的ScrollView包含多个LinearLayout S,它们又包含在标题和一个GridView。 基本上我做了包含属于该类别的图像的标题的分类部分。 GridView必须有一个灵活的高度。

我发现很多关于覆盖onMeasure()的答案,但它只适用于某些设备,并非全部。高度最终将为1或3或仅为0,只显示图像的几个像素。

StretchingGridView

我用这个代码重写了drawableStateChanged()方法,通过@灵感Karitsa的解决方案:

@Override 
public void drawableStateChanged() { 
    getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 

     @Override 
     public void onGlobalLayout() { 
      getViewTreeObserver().removeOnGlobalLayoutListener(this); 
      View lastChild = getChildAt(getChildCount() - 1); 
      if (lastChild != null) { 
       int height = Math.max(lastChild.getBottom(), getColumnWidth()); 
       float child = getAdapter().getCount(); 
       float col = getNumColumns(); 
       int rows = (int) Math.ceil(child/col); 
       height = rows * getColumnWidth() + (getHorizontalSpacing() * rows-1); 
       setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, height)); 
      } 
     } 
    }); 
} 

注:我的GridView的使用方的图像,所以我立足其宽度高度。我不认为它适用于灵活的网格物体高度。