alanlo alanlo - 1 month ago 8
Android Question

Views are not showing if I replace "include" tag with custom view class tag in layout xml file, why?

I've followed the part "Create compound view" in this guide. In one of the activity in my application there is views defined as below:

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

<!-- some other subviews... -->

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">

<!-- some other subviews... -->

<include
android:id="@+id/myHeaderView"
layout="@layout/view_my_header"></include>

</FrameLayout>
</LinearLayout>


While the custom
myHeaderView
has its layout defined in a xml file as below:

<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="250dip"
android:orientation="vertical"
android:background="@android:color/transparent">

<View
android:layout_height="5dip"
android:layout_width="match_parent"
app:layout_aspectRatio="100%"
android:background="@android:color/holo_green_light" />

<View
android:id="@+id/yellowView"
app:layout_heightPercent="50%"
app:layout_aspectRatio="100%"
android:layout_width="120dp"
android:layout_height="120dp"
android:background="@android:color/holo_orange_light"
android:layout_marginBottom="12dp"
android:layout_marginLeft="12dp"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true" />

<View
android:id="@+id/redView"
app:layout_heightPercent="40%"
app:layout_aspectRatio="200%"
android:background="@android:color/holo_red_light"
android:layout_width="200dip"
android:layout_height="100dip"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true" />

<View
android:layout_height="5dip"
android:layout_width="match_parent"
app:layout_aspectRatio="100%"
android:background="@android:color/holo_green_light"
android:layout_alignParentBottom="true"/>

</android.support.percent.PercentRelativeLayout>


Basically it should be looking like this:

enter image description here

It runs well and the custom view is showing as expected. However, if I replace the
include
tag of the custom view element in the xml with the following one:

<com.myDomain.myHeaderView
android:id="@+id/myHeaderView"
android:layout_width="match_parent"
android:layout_height="250dip"
android:orientation="vertical"
android:background="@android:color/transparent"/>


And update my constructors for the custom class
MyHeaderView
as below:

public MyHeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}

// some other constructor implementations, which they all call "initView(context)"

private void initView(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.view_my_header, this, true);
}


The subviews (e.g. the yellow view) of the custom header view will become disappeared. I checked with Device Monitor's layout view, seems that the size of the header view as well as its subviews are normal. But for some reasons I don't know, they are not visible.

Am I doing something wrong? I understand that the
include
tag is indicating that I am re-using the layout component defined by the corresponding file, but I would like to have the custom view referenced as class
MyHeaderView
instead of
ViewGroup
, so I can invoke methods defined in it hence updating the views, how can I achieve this?

Thanks!

Answer

You can try to put <include> inside <MyHeaderView> instead of inflating in MyHeaderView:

<com.myDomain.MyHeaderView
android:id="@+id/myHeaderView"
android:layout_width="match_parent"
android:layout_height="250dip"
android:orientation="vertical"
android:background="@android:color/transparent">

    <include        
        layout="@layout/view_my_header"/>

</com.myDomain.MyHeaderView>