web-dev-qa-db-ja.com

レイアウト付きのカスタムビュー

oK、

私がやろうとしているのは、デフォルトのレイアウト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>

ご覧のとおり、クラスはcom.lam.customview.CustomDisplayViewと呼ばれ、IDはcustom_display_view1です。

現在com.lam.customview.CustomDisplayViewクラスで、コントロール/ウィジェットをプログラムで作成したくないため、custom_display_view.xmlと呼ばれる別のレイアウトを使用します。

custom_display_view.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"
    >
    <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>

私がやろうとしました:

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

...

しかし、このエラー、「03-08 20:33:15.711:ERROR/onCreate(10879):Binary XML file line#8:Error inflating class 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);

...

しかし、このエラー、「03-08 20:28:47.401:ERROR/CustomDisplayView(10806):Resource ID#0x7f050002 type#0x12 is not valid」

また、誰かが提案したように、このようにすると、custom_display_view.xmlがカスタムビュークラスにどのように関連付けられるかがわかりません。

ありがとう。

34
user270811

私はまったく同じ問題を抱えていましたが、問題は私が間違ったIDを使用していたことでした...そしてそれはあなたもそうであるように見えます。

参照する必要があります

R.layout.custom_display_view

-ない-

R.id.custom_display_view

70
Rino Farina

このブログ投稿は、私が何をすべきかを非常に理解するのに役立ちました http://trickyandroid.com/protip-inflating-layout-for-your-custom-view/ 。ブログの投稿が消えた場合のコードの一部を次に示します。

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

このレイアウトでは:

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

コントロールは次のように含まれています。

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

Com.trickyandroid.customview.app.viewは、クラスカードの名前空間です。私にとって新しいことの1つは、「マージ」タグでした。これは、最終的には含まれるドキュメントのCardタグと同じノードになります。

8

次の方法で、cutom_display_viewをカスタムクラスに展開できます。

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

レイアウトを膨らませたら、ビューインスタンスへの参照を渡して、ルートとして識別する必要があります。呼び出す代わりに:

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

コール:

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

参照: ドキュメント

4

行#8は、最初のレイアウトのカスタムビューです。間違ったレイアウトをロードしようとしているので、それ自体を再帰的にロードしようとしていますか? (私はちょうど同じことをしました)

あなたも持っています:

 R.layout.custom_display_view

vs.

 R.id.custom_display_view1

終わりに1があります...どれですか?

0
Jay

使用してみてください

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