2016-04-29 5 views
0

私はAndroidで比較的新しいiOS開発者です。コントローラロジックとビュー定義を分離する再利用可能なコンポーネントを作成しようとしています。さまざまなxibファイルやストーリーボードレイアウトで使用できるクラスを定義するiOS IBOutletsに似たパターンが必要です。XML子どものカスタムAndroidコンポーネント

たとえば、カスタムプログレスバーコンポーネントを作成したいとします。私は、ユーザーが必要な子どもたちを提供し、それらをxmlで別々にデザインしてスタイルすることができるようにしたい。

ここで私が達成しようとしているもののいくつかの擬似コードです:

layout.xml

<FrameLayout> 
    <!-- A vertical progress bar --> 
    <CustomProgressBar> 
     <LinearLayout orientation="vertical"> 
      <ImageView id="@+id/bar" src="@drawable/bar_image" /> 
      <TextView id="@+id/label" text="Bar 1"/> 
     </LinearLayout> 
    </CustomProgressBar> 

    <!-- A horizontal bar using same controller class --> 
    <CustomProgressBar> 
     <LinearLayout orientation="horizontal"> 
      <ImageView src="@drawable/background_image" /> 
      <ImageView id="@+id/bar" src="@drawable/bar_image" /> 
      <TextView id="@+id/label" text="Bar 1"/> 
     </LinearLayout> 
    </CustomProgressBar> 
<FrameLayout> 

その後、私のカスタムクラスは、次のようになります。上記の例では

public class CustomProgressBar extends FrameLayout { 
    private ImageView bar; 
    private TextView label; 
    . 
    . 

    @Override 
    protected void onFinishInflate() { 
     super.onFinishInflate(); 

     // Store the references of the components 
     bar = (ImageView) findViewById(R.id.bar); 
     label = (TextView) findViewById(R.id.label); 

     // Now I should be able to write general code for this component 
     // using the reference components I found 
    } 
} 

開発者は2つのCustomProgressBarsを同じxmlファイルでインスタンス化しています。しかし、各バーのレイアウトは大きく異なります(子の表示ツリーと向きが異なります)。明らかな問題は、xmlのさまざまなビューで同じIDを使用しているため、XMLがコンパイルされないことです。コンパイルの問題を解決するために、私はID名を変更することができましたが、コントローラクラスはそれらの子への参照を見つける方法を知らないでしょう。

この問題にアプローチする別の方法はありますか?

答えて

0

ViewGroupには、getChildCountgetChildAtと呼ばれる方法があり、子ビューをインデックスでプルできるようになります。

それでは、あなたがしなければならないだろうことのようなものです:あなたはまた、手動でonLayoutメソッドをオーバーライドする必要がそれらを画面に描画するためにこれらを使用することを探しているなら

@Override 
protected void onFinishInflate() { 
    super.onFinishInflate(); 

    getProgressViews(this); 
} 

private ImageView bar; 
private TextView label; 

private void getProgressViews(ViewGroup viewGroup) { 
    int childCount = viewGroup.getChildCount(); 
    for (int i = 0; i < childCount; i++) { 
     View view = viewGroup.getChildAt(i); 

     if (view.getClass().getSuperclass() == ViewGroup.class) { 
      getProgressViews((ViewGroup) view); 
     } 
     if (view instanceof ImageView) { 
      bar = (ImageView) view; 
     } 
     if (view instanceof TextView) { 
      label = (TextView) view; 
     } 
    } 
} 

+0

投稿した2番目の例を見ると、コンポーネントは2つのImageViewを区別する方法を知らないため、これはうまくいかない。上記の例では、最後のImageViewがそのバーであると仮定していますが、これはすべてのUIデザインで真ではない可能性があります。 – cacholonu

+0

はい、ImageViewで背景と画像を設定することができますが、2つの異なるImageViewを使用する必要はありません。また、2つで本当にやりたいのであれば、簡単にコンテンツの説明を追加して区別することができます。 – w9jds

+0

これは理にかなっていますが、私は にどんなタイプのレイアウトや任意の組み合わせの子どももどんな順序でも持っていて、コンポーネントがまだ動作しているはずであるという希望です。私は内容の記述が何であるか分かりませんので、私はそれを見ていきます。 – cacholonu

関連する問題