0

私はAndroidにかなり慣れていないので、Androidアプリケーションでカスタムコンポーネントを作成しようとしています。これを行うために、FrameLayoutを拡張して、カスタムコンポーネントをビューの上部にあるスピナーで構成できるようにします(最終的にはビューに描画しますが、現時点では空白になっています)。

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"?>
<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の関連ビットです:

<?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>

うまくいけば、それはある程度意味があります。任意の洞察をいただければ幸いです。

トム

4

2 に答える 2

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
                }
        }
    }
于 2012-03-22T20:08:31.523 に答える
0

あなたは子供たちを繰り返すことができます...

getChildCount();
getChildAt(index);

次に、子IDを探しているものと比較できます。

于 2012-03-22T20:14:04.137 に答える