5

Je reçois une exception de pointeur null dans ma vue personnalisée (qui est dérivée d'un LinearLayout) car elle ne peut pas trouver ses vues enfant. Voici le code:La mise en page n'est pas gonflée dans le composant personnalisé 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."); 
     } 
    } 
} 

est ici la mise en page (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> 

Et voici comment je l'ai mis dans le fichier XML:

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

Mais lorsque je tente pour prévisualiser dans l'éditeur de disposition, je reçois un NPE sur mText.setText(...) car getViewById() renvoie null.

Que se passe-t-il?

Précision

La raison pour laquelle je pense que cela fonctionne, si je ne

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

tout fonctionne bien. N'est-ce pas ce que fait l'inflateur de mise en page lorsqu'il passe par un fichier de mise en page? Dans tous les cas, comment puis-je gérer les deux situations correctement (sans obtenir des vues imbriquées inutiles)?

+0

Où est ' 'a Pourquoi votre déclaration 'android: id' n'est-elle pas la première à la déclarer dans la mise en page? – codeMagic

+0

Je n'ai pas besoin d'un identifiant là-bas. – Timmmm

Répondre

4

Dans votre fichier XML, vous essayez d'utiliser une classe de vue personnalisée (com.example.views.MyView) et dans le même temps, essayez d'ajouter un TextView à l'intérieur. Ce n'est pas possible.

Voici ce que vous devez changer:

Vous devez gonfler le fichier XML dans le code:

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

et modifier le fichier de mise en page XML comme ceci:

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

Mais si je fais myview = (MyView) inflater.inflate (R.layout.my_view, null, false) 'dans un autre code cela fonctionne très bien. Peut-être que c'est un bug dans l'éditeur de mise en page (ne serait pas le premier!). De plus, vous devriez utiliser un '' si vous allez le faire comme vous l'avez écrit. – Timmmm

+0

Bien sûr, cela fonctionne. C'est juste que tout ce que vous mettez dans l'élément XML '' sera ignoré. C'est pourquoi le TextView est introuvable. – fiddler

+0

Non je veux dire si je fais alors 'myview.findViewById (R.id.text)' qui trouve la vue bien. Il semble que l'inflateur d'agencement se comporte différemment s'il gonfle le composant personnalisé directement lorsqu'il gonfle le composant personnalisé * dans une autre disposition. Je vais mettre à jour la question pour clarifier. – Timmmm

Questions connexes