2012-03-22 51 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