2012-03-22 6 views
0

저는 Android가 처음이므로 안드로이드 애플리케이션에 맞춤 구성 요소를 만들려고합니다. 이렇게하려면 FrameLayout을 확장하여 내 사용자 지정 구성 요소가보기 상단의 회 전자로 구성 될 수 있도록합니다. (결국에는보기에서 그리기는하지만 현재는 비어 있습니다.)Android : 부풀린 맞춤 구성 요소 내에서 xml 리소스에 액세스하는 방법

FrameLayout을 확장하는 클래스 내에서 xml에 배치 한 회 전자 버튼을 설정하고 싶습니다. 그러나 해당 클래스 내에서 findViewById를 호출하면 null이 반환됩니다. 답을 읽는 것부터 비슷한 문제가 나오는 곳까지, 나는 activity에서 findViewById를 호출해야한다는 것을 모았습니다. 실제로 활동을 확장하는 클래스에서 스피너를 설정하면 모든 것이 잘 동작합니다. 한 가지 해결책은 액티비티를 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!"); 
      } 

    } 

} 

내 활동 클래스는 거대한이지만, oscilliscope이 버튼을 눌러에 팽창하므로 관련 섹션 (I) 생각입니다 :

:

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> 

희망 몇 가지 의미가 있습니다 : 16,

<?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()이라는 재정의 함수로 이동하십시오. 당신이 ...

getChildCount(); 
getChildAt(index); 

자식들에 대해 반복 할 수

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를 비교할 수 있습니다.

+0

나는 이해하지 못한다. 당신이 정교 할 수 있니? – ForeverWintr