Search code examples
androidandroid-linearlayoutandroid-custom-view

Children of extended LinearLayout defined in XML do not show


In my project I have screens where the same pattern is repeated a lot - it's basically a container for views consisting of a linear layout with the heading, image and specific background. To avoid copying and pasting the same sequence multiple times I thought I could create a compound view, extend LinearLayout and define all the "styling" there, and then just use that component in my layouts. I followed howto's and examples and got my compound view to work. However, all examples I've seen use the resulting view as follows:

<com.myproject.compound.myview
    ...some attrs...
/>

I.e. no children are added via XML. I need to use it like this:

<com.myproject.compound.myview
    ...some attrs...>
    <TextView 
        ..../>
    ...other views...

</com.myproject.compound.myview>

Since I'm extending LinearLayout I was expecting "myview" tag to work like LinearLayout too, but for some reason items I put inside do not get drawn. Is there something I need to do specially to get the inner views to draw?

My extended LinearLayout is very simple, I am not overriding any methods and just calling super in constructor and inflating the layout like this:

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.my_compound_view, this, true);

UPDATE: I thought I'd add an XML as a point of reference:

<?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="match_parent"
android:orientation="vertical" 
android:background="@drawable/bg"
android:padding="12dp">
<TextView 
    android:id="@+id/section_title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="#FF0000AA"        />
<ImageView
    android:layout_width="match_parent"
    android:layout_height="2dp"
        android:src="@drawable/line"        />
</LinearLayout>

Solution

  • Actually found a more elegant solution. Just need to use merge tag instead of LinearLayout in the compound view. All boils down to:

    <merge xmlns:android="http://schemas.android.com/apk/res/android"
        <TextView 
            android:id="@+id/section_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="HEADING"
            android:textColor="#FF0000AA"        />
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="2dp"
            android:src="@drawable/line"        />
    </merge>
    

    and

    public class CompoundLayout extends LinearLayout{
        public CompoundLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            LayoutInflater inflater = (LayoutInflater) context
               .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            inflater.inflate(R.layout.compound_layout, this, true);
        }
    }
    

    Main layout:

    <com.testbench.CompoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFDDEE"
        android:orientation="vertical">
        <TextView 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Inner text"
                android:layout_gravity="center_horizontal"/>        
    </com.testbench.CompoundLayout>