2012-03-22 9 views
0

私はAndroidがかなり新しく、Androidコンポーネントでカスタムコンポーネントを作成しようとしています。これを行うには、FrameLayoutを拡張して、カスタムコンポーネントがビューの上にあるスピナーで構成されるようにします(私は最終的にビューに描画しますが、現時点では空白です)。Android:膨大なカスタムコンポーネント内からxmlリソースにアクセスする方法

FrameLayoutを拡張するクラス内で、私はxmlでレイアウトしたスピナーボタンを設定したいと思います。ただし、そのクラス内からfindViewByIdを呼び出すとnullが返されます。答えを読んでから同様の問題を発見するまで、私はアクティビティからfindViewByIdを呼び出す必要があることを知ります(実際に、アクティビティを拡張するクラスからスピナーを設定すると、すべて正常に動作します)。 1つの解決策は、FrameLayoutクラスのコンストラクタにアクティビティを渡すことです。しかし、私はlayoutinflaterを使ってそれを膨張させるので、FrameLayoutクラスのコンストラクタを自分自身で呼び出すことはありません。私はレイアウトインフレータが私のFrameLayoutクラスのコンストラクタを呼び出すと仮定し、コンストラクタ呼び出しに引数を追加する方法がわかりません。

誰かが私が間違っていることを教えてもらえますか、これにどのように接近すべきですか?

ここに私のコードの簡易版です。

マイカスタムでframeLayoutクラス:

package com.example.myoscilloscope.gui; 

import android.app.Activity; 
import android.content.Context; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.widget.FrameLayout; 
import android.widget.Spinner; 

import com.example.myoscilloscope.R; 

public class Oscilloscope extends FrameLayout { 

    //variables 
    private Spinner chanSelector; //the channel selector 

    // overloading constructors 
    public Oscilloscope(Context context) { this(context, null, 0); } 
    public Oscilloscope(Context context, AttributeSet attrs) { this(context, attrs, 0); } 

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

      //set up the spinner. 
      chanSelector = (Spinner) findViewById(R.id.channel_spinner); 

      if(chanSelector == null){ 
       Log.d("FROMTOM", "CHANNELSELECTOR IS NULL!"); 
      } 

    } 

} 

マイアクティビティクラスは巨大ですが、オシロスコープは、ボタンを押すに膨張され、その関連セクション(私は)だと思うです:

import com.example.myoscilloscope.gui.Oscilloscope; 

// ... 

public void addchannel(View v){ 
    //this initialization is actually done elsewhere, but I've copied it here 
    // for simplicity's sake 
    private LayoutInflater oscilloscopeInflater; 
    LinearLayout myOscilloscopeHolder; 

    oscilloscopeInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    myOscilloscopeHolder = (LinearLayout)findViewById(R.id.oscilloscopeHolder); 

    Oscilloscope myOscilliscope = (Oscilloscope)oscilloscopeInflater.inflate(R.layout.oscilloscope, myOscilloscopeHolder, false);  
    myOscilloscopeHolder.addView(trOscilloscopes[trChannelsDisplayed]); 
} 

はここに私のメインプログラムによって膨張された私のOscilloscope.xmlファイル、です

<?xml version="1.0" encoding="UTF-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="@color/background_color" > 

    <LinearLayout 
     android:id="@id/oscilloscopeHolder" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:layout_above="@id/rg_channels" 
     android:layout_toLeftOf="@id/HistogramArea" 
     android:orientation="vertical" 
     android:background="#FFFFFF" > 


    </LinearLayout> 
</RelativeLayout> 

うまくいけば、いくつかの意味があります:

<?xml version="1.0" encoding="utf-8"?> 
<com.example.myoscilloscope.gui.Oscilloscope xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/oscilloscope" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:layout_weight="1" > 

    <com.example.myoscilloscope.gui.Oscillator 
     android:id="@+id/oscillator" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" /> 

     <Spinner 
     android:id="@+id/channel_spinner" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="bottom" 
    /> 


</com.example.myoscilloscope.gui.Oscilloscope> 

そして、ここでは私のmain.xmlの該当ビットです。どんな洞察も高く評価されるだろう。

トム

答えて

4

ごめんなさいこれらのビューが違うことに気付かなかった...これは問題を解決するはずです。

この時点でインフレが終了していないため、コンストラクタでfindViewByIdを使用しないでください。 findViewByIdコードをonFinishInflate()というオーバーライドされた関数に移動します。

public class Oscilloscope extends FrameLayout { 

     private Spinner chanSelector; //the channel selector 

     public Oscilloscope(Context context) { this(context, null, 0); } 
     public Oscilloscope(Context context, AttributeSet attrs) { this(context, attrs, 0); } 
     public Oscilloscope(Context context, AttributeSet attrs, int defStyle) { 
      super(context, attrs, defStyle); 
     } 

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

       chanSelector = (Spinner) findViewById(R.id.channel_spinner); 

       if (chanSelector == null) { 
        //Should never get here 
       } 
     } 
    } 
+0

お返事ありがとうございます。私がこの質問に答えようとするたびにあなたが通知を受けているなら、私はコメントにコードを挿入する方法を理解できません。申し訳ありません。 とにかく、私はあなたが示唆したように、chanSelector変数はnullに戻ります。他のアイデア? – ForeverWintr

+0

あなたの修正を追加するために私の質問を編集しました。 – ForeverWintr

+0

もちろん、xmlで指定したIDがfindViewByIdで検索したIDと同じ場合は、他の問題です。私の愚かさを修正した後、あなたのソリューションは機能します!ありがとう。 – ForeverWintr

0

あなたは次にあなたが探しているもので、子IDを比較することができます...

getChildCount(); 
getChildAt(index); 

で子供を反復処理することができます。

+0

私は理解できません。あなたは精緻化できますか? – ForeverWintr

関連する問題