web-dev-qa-db-fra.com

vue personnalisée avec mise en page

d'accord,

ce que j'essaie de faire est d'incorporer une vue personnalisée dans la mise en page par défaut main.xml:

<?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 disposition appelée custom_display_view.xml parce que je ne veux pas créer par programmation des contrôles/widgets.

custom_display_view.xml n'est qu'un bouton et une image dont je souhaite modifier 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 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 a obtenu cette erreur, "03-08 20: 33: 15.711: ERREUR/onCreate (10879): ligne de fichier XML binaire # 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: ERREUR/CustomDisplayView (10806): l'ID de ressource # 0x7f050002 type # 0x12 n'est pas valide"

aussi, si je le fais de cette façon, comme quelqu'un l'a suggéré, il n'est pas clair pour moi comment le custom_display_view.xml est associé à la classe de vue personnalisée.

merci.

34
user270811

J'ai eu exactement le même problème, et le problème était que j'utilisais le mauvais identifiant ... et on dirait que vous l'êtes aussi.

Vous devriez référencer

R.layout.custom_display_view

-ne pas-

R.id.custom_display_view

70
Rino Farina

Ce billet de blog m'a aidé à comprendre quoi faire énormément http://trickyandroid.com/protip-inflating-layout-for-your-custom-view/ . Dans le cas où l'article de blog disparaît, 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 noms de la carte de classe. 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 document contenant.

8
Frank Schwieterman

Vous pouvez gonfler cutom_display_view dans votre classe personnalisée en:

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);
            }
}
7
herbertD

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

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

Appel:

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

Voir: Les documents

4

La ligne # 8 est votre vue personnalisée dans la première mise en page. Essayez-vous de charger la mauvaise disposition, donc essayez-vous de se charger récursivement? (Je viens de faire la même chose)

vous avez aussi:

 R.layout.custom_display_view

vs.

 R.id.custom_display_view1

avec le 1 à la fin là ... lequel est-ce?

0
Jay

Essayez d'utiliser

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