5

Ich bekomme eine Null-Zeiger-Ausnahme in meiner benutzerdefinierten Ansicht (die von einem LinearLayout abgeleitet ist), weil es seine untergeordneten Ansichten nicht finden kann. Hier ist der Code:Layout nicht aufgeblasen in android benutzerdefinierten Komponente

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."); 
     } 
    } 
} 

Hier ist das 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> 

Und hier ist, wie ich es in der XML-Datei setzen:

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

Aber wenn ich versuche, Um eine Vorschau im Layout-Editor zu erhalten, erhalte ich eine NPE unter mText.setText(...), weil getViewById()null zurückgibt.

Was ist los?

Klärung

Der Grund, warum ich dies funktioniert erwarten ist, wenn ich

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

alles funktioniert. Ist das nicht der Layout-Inflator, wenn er eine Layout-Datei durchläuft? In jedem Fall, wie kann ich beide Situationen richtig behandeln (ohne sinnlose verschachtelte Ansichten)?

+0

Wo ist ' 'a nd warum ist das nicht deine android: id-aussage, wo du es zuerst im layout deklarierst? – codeMagic

+0

Ich brauche keine ID dort. – Timmmm

Antwort

4

In Ihrer XML-Datei versuchen Sie, eine benutzerdefinierte Ansichtsklasse (com.example.views.MyView) zu verwenden und gleichzeitig zu versuchen, eine TextView-Datei hinzuzufügen. Es ist nicht möglich.

Hier ist, was Sie ändern müssen:

Sie müssen XML-Datei im Code aufblasen:

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

Und die XML-Layout-Datei wie folgt ändern:

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

Aber wenn ich 'myview = (MyView) inflater.inflate (R.layout.my_view, null, falsch)' in einigen anderen Code funktioniert es gut. Vielleicht ist es ein Fehler im Layout-Editor (wäre nicht der erste!). Plus sollten Sie eine '' verwenden, wenn Sie es so machen werden, wie Sie es geschrieben haben. – Timmmm

+0

Natürlich funktioniert es. Es ist nur so, dass alles, was Sie in das '' XML-Element einfügen, ignoriert wird. Deshalb kann die TextView nicht gefunden werden. – fiddler

+0

Nein, ich meine, wenn ich dann 'myview.findViewById (R.id.text)', die die Ansicht in Ordnung findet. Es scheint, als ob sich der Layout-Inflator anders verhält, wenn er die benutzerdefinierte Komponente direkt aufbläht, wenn er die benutzerdefinierte Komponente * innerhalb * eines anderen Layouts aufbläht. Ich werde die Frage aktualisieren, um zu klären. – Timmmm

Verwandte Themen