5

Ricevo un'eccezione di puntatore nullo nella mia vista personalizzata (che deriva da un LinearLayout) perché non riesce a trovare le sue viste secondarie. Ecco il codice:Layout non gonfiato nel componente personalizzato Android

public class MyView extends LinearLayout 
{ 
    public MyView(Context context, AttributeSet attrs) 
    { 
     this(context, attrs, 0); 
    } 

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

    private TextView mText; 

    @Override 
    protected void onFinishInflate() 
    { 
     super.onFinishInflate(); 
     mText = (TextView) findViewById(R.id.text); 

     if (isInEditMode()) 
     { 
      mText.setText("Some example text."); 
     } 
    } 
} 

Ecco il layout (my_view.xml):

<?xml version="1.0" encoding="utf-8"?> 
<com.example.views.MyView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" > 

    <TextView 
     android:id="@+id/text" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:layout_weight="1" 
     android:gravity="center" 
     android:ellipsize="end" 
     android:maxLines="4" 
     android:paddingLeft="8dp" 
     android:paddingRight="8dp" 
     android:text="Some text" /> 

</com.example.views.MyView> 

ed ecco come l'ho messo nel file XML:

<com.example.views.MyView 
     android:id="@+id/my_view" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

Ma quando provo per visualizzarlo in anteprima nell'editor di layout, ottengo un NPE su mText.setText(...) perché getViewById() restituisce null.

Cosa sta succedendo?

Chiarimento

La ragione per cui mi aspetto che questo lavoro, è se faccio

MyView v = (MyView)inflater.inflate(R.layout.my_view); 
((TextView)v.findViewById(R.id.text)).setText("Foo"); 

tutto funziona bene. Non è questo ciò che fa il gonfiaggio del layout quando attraversa un file di layout? In ogni caso, come posso gestire entrambe le situazioni correttamente (senza ottenere viste nidificate inutili)?

+0

Dove si trova ' 'a e perché non è la tua istruzione 'android: id' dove la dichiari prima nel layout? – codeMagic

+0

Non ho bisogno di un id lì. – Timmmm

risposta

4

Nel file XML si sta tentando di utilizzare una classe di visualizzazione personalizzata (com.example.views.MyView) e allo stesso tempo si tenta di aggiungere un TextView all'interno. Non è possibile.

Ecco cosa è necessario cambiare:

È necessario gonfiare file XML nel codice:

public MyView(Context context, AttributeSet attrs, int defStyle) 
{ 
    super(context, attrs, defStyle); 
    LayoutInflater.from(context).inflate(R.layout.<your_layout>.xml, this); 
} 

e modificare il file di layout XML come questo:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:orientation="horizontal" > 

<TextView 
    android:id="@+id/text" 
    android:layout_width="0dp" 
    android:layout_height="match_parent" 
    android:layout_weight="1" 
    android:gravity="center" 
    android:ellipsize="end" 
    android:maxLines="4" 
    android:paddingLeft="8dp" 
    android:paddingRight="8dp" 
    android:text="Some text" /> 

</LinearLayout> 
+0

Ma se faccio 'myview = (MyView) inflater.inflate (R.layout.my_view, null, false)' in qualche altro codice funziona correttamente. Forse è un bug nell'editor di layout (non sarebbe il primo!). Inoltre dovresti usare un '' se hai intenzione di farlo nel modo in cui hai scritto. – Timmmm

+0

Ovviamente funziona. È solo che qualunque cosa tu abbia inserito nell'elemento '' l'elemento XML verrà ignorato. Ecco perché non è possibile trovare TextView. – fiddler

+0

No Intendo se poi faccio 'myview.findViewById (R.id.text)' che trova bene la vista. Sembra che il sistema di gonfiaggio del layout si comporti diversamente se gonfia il componente personalizzato direttamente quando gonfia il componente personalizzato * all'interno di * un altro layout. Aggiornerò la domanda per chiarire – Timmmm

Problemi correlati