custom view with layout

64,402

Solution 1

I had the exact same issue, and the problem was that I was using the wrong ID... and it look's like you are too.

You should be referencing

R.layout.custom_display_view

-not-

R.id.custom_display_view

Solution 2

This blog post helped me understand what to do immensely http://trickyandroid.com/protip-inflating-layout-for-your-custom-view/. In case the blog post disappears, here are some parts of the 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);
    }
}

with this layout:

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

The control is included like:

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

Where com.trickyandroid.customview.app.view is the namespace of class card. One thing that was new to me was the "merge" tag, which ends up being the same node as the Card tag in the containing doc.

Solution 3

You can inflate the cutom_display_view into your custom class by:

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

Solution 4

When you inflate your layout, you should pass in a reference to the view instance to identify it as the root. So instead of calling:

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

Call:

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

See: The docs

Share:
64,402
user270811
Author by

user270811

Updated on September 23, 2020

Comments

  • user270811
    user270811 over 3 years

    ok,

    what i am trying to do is to embed a custom view in the default layout 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>
    

    as you can see the class is called com.lam.customview.CustomDisplayView, with the id of custom_display_view1.

    now in the com.lam.customview.CustomDisplayView class, i want to use another layout called custom_display_view.xml because i don't want to programmatically create controls/widgets.

    custom_display_view.xml is just a button and an image, the content of which i want to change based on certain 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>
    

    i tried to do:

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

    ...

    but got this error, "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);
    

    ...

    but got this error, "03-08 20:28:47.401: ERROR/CustomDisplayView(10806): Resource ID #0x7f050002 type #0x12 is not valid "

    also, if i do it this way, as someone has suggested, it's not clear to me how the custom_display_view.xml is associated with the custom view class.

    thanks.