2012-12-14 9 views
12

[OK]を、私は、次の例に似たレイアウトXML持っているので:アンドロイド:タイプ別のビューをどのように見つけるか

<?xml version="1.0" encoding="utf-8"?> 
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:background="@drawable/tile_bg" > 

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    android:paddingTop="10dp" > 

    <LinearLayout 
     android:id="@+id/layout_0" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" > 

     <!-- view stuff here --> 
    </LinearLayout> 

    <!-- more linear layouts as siblings to this one --> 

</LinearLayout> 

を私は実際には約7のLinearLayoutのアイテムを持っているlayout_0などから増加IDを持つ各ルートLinearLayoutの下にあるすべてのLinearLayoutアイテムを取得できるようにしたいと思います。私はルートにidを入れ、idで他のすべてのものを見つける必要がありますか、またはそれらをタイプで得ることができますか?

私はレイアウトを膨らませるために使用するコードは次のとおりです。

私はあなたがのViewGroupの子供を反復することができますが、これが唯一のビューであることをどこかで読みました。

子どもたちを種類別にまとめるにはどうすればよいですか?

答えて

24

これは正しい軌道に乗るはずです。

LinearLayout rootLinearLayout = (LinearLayout) findViewById(R.id.rootLinearLayout); 
int count = rootLinearLayout.getChildCount(); 
for (int i = 0; i < count; i++) { 
    View v = rootLinearLayout.getChildAt(i); 
    if (v instanceof LinearLayout) { 
     ... 
    } 
} 
+1

範囲外の例外が発生しないようにi Andres

+0

'instanceof'は重い操作であることに注意してください。このAproachは、多くのchlidrenを持つビューでは遅くなる可能性があります。 –

+0

@EmrysMyrooin高価な呼び出しは、入力間の遅延を引き起こす場合にのみ実際に問題になります。これがonCreateメソッド内での初期化だけであれば、ユーザが何とか何かをやる機会を与えられていないので、あまり重要ではありません。しかし、見つけたのは7人しかいなければ、これは本当に必要なことではありません。ここでも最適化が必要です。ループは高価で、UIループをぶら下げている。 –

1

あなたはのLinearLayoutルートにIDを追加する必要があります

<LinearLayout 
    android:id="@+id/root" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    android:paddingTop="10dp" > 

    <LinearLayout 
     android:id="@+id/layout_0" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" > 

     <!-- view stuff here --> 
    </LinearLayout> 

    <!-- more linear layouts as siblings to this one --> 

</LinearLayout> 

を次にいつものように全体のレイアウトを膨らま:

ルートLinearLayout上のホールドを取得します

LinearLayout root = (LinearLayout) view.findViewById(R.id.root); 

LinearLayout[] children = new LinearLayout[root.getChildCount()]; 

for (int i = 0; i < root.getChildCount(); i++) { 
    children[i] = (LinearLayout) root.getChildAt(i); 
} 
1

ルートビーを渡すこのDFSメソッドの引数としてW:あなたは、レイアウトのルート要素がLinearLayoutまたは他のレイアウトなどの任意のサブクラスであることがわかっている場合

private List<LinearLayout> mArr = new ArrayList<LinearLayout>(); 

private void getLinearLayouts(ViewGroup parent) { 
    int childCount = parent.getChildCount(); 
    for (int i = 0; i < childCount; i++) { 
     View child = parent.getChildAt(i); 
     if (child instanceof ViewGroup) { 
      getLinearLayouts((ViewGroup) child); 
      if (child instanceof LinearLayout) 
       mArr.add((LinearLayout) child); 
     } 
    } 
} 
3

あなたは安全にViewGroupにあなたの結果ビューをキャストすることができます

ViewGroup vg = (ViewGroup)view; 

をし、必要に応じて使用してください。あなたは常にルートコンテナのレイアウト一種類のみ使用は、あなたがすなわち、その型にキャストできることがわかっている場合:

LinearLayout vg = (LinearLayout)view; 
1

は、私はちょうどより多くの一般的なものを追加したいが、あなたは維持する必要がありますこれを行うには重いアプローチであることを念頭に置いてください。 (tClass.isInstance(child)を参照)

private static <T extends View> ArrayList<T> getChildrenOfParentWithClass(ViewGroup parent, Class<T> clazz) 
{ 
    ArrayList<T> children = new ArrayList<>(); 

    int childCount = parent.getChildCount(); 
    for (int i = 0; i < childCount; i++) 
    { 
     View child = parent.getChildAt(i); 
     if (child instanceof ViewGroup) 
     { 
      children.addAll(getChildrenOfParentWithClass((ViewGroup) child, clazz)); 
      if (child.getClass().equals(clazz)) 
      { 
       children.add((T) child); 
      } 
     } 
    } 

    return children; 
} 
+0

最初の 'if'ブロックのうち、2番目の' if'ブロックを挿入する必要があります! –

0

@ ChristopheCVBの答えのように、だけでなく、継承をサポートしています。

はとにかく、ここのコードです。

public static <T extends View> ArrayList<T> getViewsByType(ViewGroup root, Class<T> tClass) { 
    final ArrayList<T> result = new ArrayList<>(); 
    int childCount = root.getChildCount(); 
    for (int i = 0; i < childCount; i++) { 
     final View child = root.getChildAt(i); 
     if (child instanceof ViewGroup) 
      result.addAll(getViewsByType((ViewGroup) child, tClass)); 

     if (tClass.isInstance(child)) 
      result.add(tClass.cast(child)); 
    } 
    return result; 
} 

と使用方法の簡単な例:

ArrayList<TextView> TextViews = getViewsByType(rootLayout, TextView.class); 

受け入れ答えをありがとうございました。

関連する問題