2012-03-22 43 views
0

我對Android相當陌生,並且正在嘗試在我的android應用程序中構建自定義組件。爲此,我擴展了FrameLayout,以便我的自定義組件可以包含一個位於視圖頂部的微調框(最終將在視圖中繪製,但此時只是空白)。Android:如何訪問膨脹的自定義組件中的xml資源

在我的擴展FrameLayout的類中,我想設置一個微調按鈕,我已經在xml中進行了佈局。但是,在該類內調用findViewById的返回null。從閱讀這裏的答案到類似的問題,我收集到,我需要從一個活動調用findViewById(事實上,如果我從擴展活動的類設置微調器,一切工作正常)。然後一個解決方案就是將一個活動傳遞給我的FrameLayout類的構造函數。然而,我從來沒有自己調用我的FrameLayout類的構造函數,因爲我使用layoutinflater來填充它。我假設佈局inflater正在調用我的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!"); 
      } 

    } 

} 

我的活動類是巨大的,但oscilliscope膨脹上的按鈕按下,因此相關部分(我覺得)是:

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

哎呀對不起,沒注意這些人不同的看法......這應該解決您的問題。

您不應該在構造函數中使用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 2012-03-23 00:14:13

+0

我編輯了我的問題來添加更正。 – ForeverWintr 2012-03-23 00:24:12

+0

當然,如果您在xml中指定的id與在findViewById中搜索的id相同,那麼它會有所幫助...那是我的其他問題。糾正我自己的愚蠢之後,你的解決方案就可以運作!謝謝。 – ForeverWintr 2012-03-23 17:42:44

0

你可以...

getChildCount(); 
getChildAt(index); 

在孩子迭代然後你就可以比較你要尋找的孩子IDS。

+0

恐怕我不明白;你能詳細說明一下嗎? – ForeverWintr 2012-03-23 00:16:41