34 votes

vue personnalisée avec mise en page

Ok,

Ce que j'essaie de faire, c'est d'intégrer une vue personnalisée dans le fichier main.xml de la mise en page par défaut :

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

    <com.lam.customview.CustomDisplayView
        android:id="@+id/custom_display_view1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/prev"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="50"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:text="@string/prev" />
    </LinearLayout>
</LinearLayout>

comme vous pouvez le voir, la classe s'appelle com.lam.customview.CustomDisplayView, avec l'id de custom_display_view1.

Maintenant, dans la classe com.lam.customview.CustomDisplayView, je veux utiliser une autre mise en page appelée custom_display_view.xml parce que je ne veux pas créer de contrôles/widgets de manière programmatique.

custom_display_view.xml est juste un bouton et une image, dont je veux changer le contenu en fonction de certaines conditions :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView 
    android:id="@+id/display_text_view1" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
    <ImageView 
    android:id="@+id/display_image_view1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content">
    </ImageView>

</LinearLayout>

J'ai essayé de le faire :

1)

public CustomDisplayView(Context context, AttributeSet attrs) {
    super(context, attrs);

    try
    {
        // register our interest in hearing about changes to our surface
        SurfaceHolder holder = getHolder();
        holder.addCallback(this);

        View.inflate(context, R.layout.custom_display_view, null);

...

mais j'ai obtenu cette erreur, "03-08 20:33:15.711 : ERROR/onCreate(10879) : Fichier XML binaire ligne n°8 : Erreur de gonflement de la classe java.lang.reflect.Constructor ".

2)

public CustomDisplayView(Context context, AttributeSet attrs) {
    super(context, attrs);

    try
    {
        // register our interest in hearing about changes to our surface
        SurfaceHolder holder = getHolder();
        holder.addCallback(this);

        View.inflate(context, R.id.custom_display_view1, null);

...

mais j'ai obtenu cette erreur, "03-08 20:28:47.401 : ERROR/CustomDisplayView(10806) : Resource ID #0x7f050002 type #0x12 is not valid "

De plus, si je procède de cette façon, comme quelqu'un l'a suggéré, je ne vois pas très bien comment le fichier custom_display_view.xml est associé à la classe de vue personnalisée.

Merci.

70voto

Rino Farina Points 806

J'ai eu exactement le même problème, et le problème était que j'utilisais le mauvais identifiant... et il semble que vous le soyez aussi.

Vous devez faire référence

R.layout.custom_display_view

-not-

R.id.custom_display_view

8voto

Frank Schwieterman Points 13519

Cet article de blog m'a beaucoup aidé à comprendre ce qu'il faut faire. http://trickyandroid.com/protip-inflating-layout-for-your-custom-view/ . Au cas où l'article du blog disparaîtrait, voici quelques parties du code :

public class Card extends RelativeLayout {
    public Card(Context context) {
        super(context);
        init();
    }

    public Card(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

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

    private void init() {
        inflate(getContext(), R.layout.card, this);
    }
}

avec cette disposition :

<?xml version="1.0" encoding="utf-8"?>

<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="@dimen/card_padding"
    android:background="@color/card_background">

    <ImageView
        ... />

    <TextView
        ... />

</merge>

Le contrôle est inclus comme :

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin">

    <com.trickyandroid.customview.app.view.Card
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/card_background"
        android:padding="@dimen/card_padding"/>

</FrameLayout>

Où com.trickyandroid.customview.app.view est l'espace de nom de la classe carte. Une chose qui était nouvelle pour moi était la balise "merge", qui finit par être le même nœud que la balise Card dans le doc contenant.

7voto

herbertD Points 1721

Vous pouvez gonfler le cutom_display_view dans votre classe personnalisée par :

public CustomDisplayView(Context context, AttributeSet attrs) {   
    super(context, attrs);           
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if(inflater != null){       
                inflater.inflate(R.layout.custom_display_view, this);
            }
}

4voto

JannieT Points 2160

Lorsque vous gonflez votre mise en page, vous devez transmettre une référence à l'instance de vue pour l'identifier en tant que racine. Ainsi, au lieu d'appeler :

View.inflate(context, R.layout.custom_display_view, null);

Appelez :

View.inflate(context, R.layout.custom_display_view, this);

Voir : Les docs

0voto

Karan Points 6418

Essayez d'utiliser

context.getLayoutInflater().inflate( R.id.custom_display_view1, null );

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X