2012-03-27 10 views

答えて

0

ここにレイアウトを置くまでは、線形レイアウトに間違った水平/垂直パラメータを設定していることが考えられます。

9

Androidのスクロール可能なビュー(ListView、GridView、ScrollView)をネストすることはできません。

次のコードを見て与えることができる:

import android.content.Context; 
import android.util.AttributeSet; 
import android.view.ViewGroup; 
import android.widget.GridView; 

public class ScrollableGridView extends GridView { 
    boolean expanded = true; 

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

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

    public ScrollableGridView(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. 
      // But do not use the highest 2 bits of this integer; those are 
      // reserved for the MeasureSpec mode. 
      int expandSpec = MeasureSpec.makeMeasureSpec(
        Integer.MAX_VALUE >> 2, 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; 
    } 
} 

をそれはScrollViewにネストされたときに、それはほとんどの作業できるようにGridViewの少し良いバージョンです。私は時には20〜30ピクセルが短すぎたり長すぎたりすることがあったので、私は「ほとんど仕事」と言った。 これは、ビューが再利用されないようにするので、通常のGridViewより重くなります。

私の場合、私はLinearLayoutを拡張し、それを使って子供を列に整列させました。それは本当に難しいことではありません - あなたが望むなら、私はあなたに例を挙げることができます。 :)

私はthis answerからGridViewの例を得ました。ここで

はのLinearLayoutに基づいてGridViewのための例です:

import java.util.List; 
import android.content.Context; 
import android.content.res.TypedArray; 
import android.util.AttributeSet; 
import android.util.TypedValue; 
import android.view.Gravity; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.LinearLayout; 

public class GridLikeLayout extends LinearLayout { 
    private static final int DEFAULT_ITEMS_PER_ROW = 1; 
    private final int DEFAULT_COLUMN_WIDTH = (int) TypedValue.applyDimension(
      TypedValue.COMPLEX_UNIT_DIP, 150, getContext().getResources() 
        .getDisplayMetrics()); 

    private int itemsPerRow = DEFAULT_ITEMS_PER_ROW; 
    private List<View> innerViews = null; 

    private int columnWidth; 

    public GridLikeLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     TypedArray a = context.obtainStyledAttributes(attrs, 
       R.styleable.GridLikeLayout); 

     // itemsPerRow = a.getInt(R.styleable.GridLikeLayout_columns, 
     // DEFAULT_ITEMS_PER_ROW); 

     try { 
      columnWidth = (int) a.getDimension(
        R.styleable.GridLikeLayout_column_width, DEFAULT_COLUMN_WIDTH); 
     } catch (UnsupportedOperationException uoe) { 
      columnWidth = (int) a.getInt(
        R.styleable.GridLikeLayout_column_width, DEFAULT_COLUMN_WIDTH); 
     } 

     setOrientation(LinearLayout.VERTICAL); 
    } 

    public GridLikeLayout(Context context) { 
     super(context); 
     setOrientation(LinearLayout.VERTICAL); 
    } 

    public void setInnerViews(List<View> innerViews) { 
     this.innerViews = innerViews; 
     processViews(); 
    } 

    public List<View> getInnerViews() { 
     return innerViews; 
    } 

    protected void processViews() { 
     if (null != innerViews) { 
      LinearLayout innerContainer = null; 
      innerContainer = generateInnerContainer(); 
      int childrenCount = innerViews.size(); 
      for (int index = 0; index < childrenCount; ++index) { 
       if (isFull(innerContainer)) { 
        addInnerContainer(innerContainer); 
        innerContainer = generateInnerContainer(); 
       } 
       View child = innerViews.get(index); 
       if (null != child.getParent()) { 
        ((ViewGroup) child.getParent()).removeView(child); 
       } 
       addInnerView(innerContainer, child); 
      } 

      addInnerContainer(innerContainer); 
     } 
    } 

    protected boolean isFull(LinearLayout innerContainer) { 
     return 0 == (innerContainer.getChildCount() % itemsPerRow) 
       && 0 < innerContainer.getChildCount(); 
    } 

    protected void addInnerView(LinearLayout innerContainer, View child) { 
     int width = LayoutParams.WRAP_CONTENT; 
     int height = LayoutParams.WRAP_CONTENT; 
     LayoutParams innerParams = new LayoutParams(width, height); 
     innerParams.weight = 1; 
     innerParams.gravity = Gravity.CENTER; 
     innerContainer.addView(child, innerParams); 
    } 

    protected void addInnerContainer(LinearLayout innerContainer) { 
     LayoutParams params = generateDefaultLayoutParams(); 
     params.width = LayoutParams.MATCH_PARENT; 
     addView(innerContainer, params); 
    } 

    protected LinearLayout generateInnerContainer() { 
     LinearLayout innerContainer; 
     innerContainer = new LinearLayout(getContext()); 
     innerContainer.setGravity(Gravity.CENTER); 
     return innerContainer; 
    } 

    public void setOnInnerViewClickListener(OnClickListener listener) { 
     for (View innerView : innerViews) { 
      innerView.setOnClickListener(listener); 
     } 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     // Sets up mListPadding 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

     int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
     int widthSize = MeasureSpec.getSize(widthMeasureSpec); 

     if (widthMode == MeasureSpec.UNSPECIFIED) { 
      if (columnWidth > 0) { 
       widthSize = columnWidth + getPaddingLeft() + getPaddingRight(); 
      } else { 
       widthSize = getPaddingLeft() + getPaddingRight(); 
      } 
      widthSize += getVerticalScrollbarWidth(); 
     } 

     int childWidth = widthSize - getPaddingLeft() - getPaddingRight(); 
     int columnsNumber = determineColumns(childWidth); 
     if (columnsNumber > 0 && columnsNumber != itemsPerRow) { 
      itemsPerRow = columnsNumber; 
      removeAllViews(); 
      processViews(); 
     } 
    } 

    protected int determineColumns(int availableSpace) { 
     int columnsNumber = itemsPerRow; 
     if (0 < columnWidth) { 
      columnsNumber = availableSpace/columnWidth; 
     } 
     return columnsNumber; 
    } 

} 

ここでは、カスタムのための私のリソースファイル属性れる:ここでは

<?xml version="1.0" encoding="utf-8"?> 
<resources> 

    <attr name="column_width" format="dimension|integer"> 
     <enum name="single_column" value="-1" /> 
    </attr> 
    <declare-styleable name="GridLikeLayout"> 
     <attr name="column_width" /> 
    </declare-styleable> 

</resources> 

は使用例です:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/layoutContainer" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 

    <ScrollView 
     android:id="@+id/itemsScroller" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" > 

     <LinearLayout 
      android:id="@+id/itemsLayout" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical" > 

      <your_package.view.GridLikeLayout 
       xmlns:my="YOUR APPLICATION PACKAGE" 
       android:id="@+id/MyGrid" 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       my:column_width="260dp" 
       android:focusable="true" 
       android:gravity="center_horizontal" 
       android:padding="5dp" > 
      </your_package.GridLikeLayout> 

      <View 
       android:id="@+id/viewSeparator" 
       android:layout_width="fill_parent" 
       android:layout_height="2dp" /> 

      <your_package.GridLikeLayout 
       xmlns:my="YOUR APPLICATION PACKAGE" 
       android:id="@+id/list" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       my:column_width="single_column" > 
      </your_package.GridLikeLayout> 

     </LinearLayout> 
    </ScrollView> 

</FrameLayout> 

例を実行する際に問題がある場合は教えてください - 私はそれを試着することはできませんnt。だから問題があれば、後でそれをチェックします。パッケージ名を変更することを忘れないでください。 "your_package"はGridLikeLayoutを保存するパッケージで、 "YOUR APPLICATION PACKAGE"はアプリケーションのパッケージです - アプリケーションマニフェストで指定されたものです。 :)

+0

私は例を与えます... – Venkat

+0

@venkat、私は私のポストに例を追加しました。助けが必要かどうか教えてください。 :) –

0

あなたの最初の解決策は動作しますが、GridViewsが私の場合のように画像キャッシュを暗示することを考慮していません。ここで最初の解決策は、スクロールを開始するたびにOutOfMemoryErrorにつながります。 画像のキャッシュを考慮したサンプルソリューションは誰か既に得られていますか?

関連する問題