Search code examples
androidandroid-layoutandroid-custom-view

layout_below does not work because of custom view


I have a custom view (MyView) which extends SurfaceView in which I override the onDraw method. I create an instance of this view dynamically with a custom constructor:

MyView myView = new MyView(...);

In this constructor I call the super(Context context) method.

After that, I wrap my custom view in a RelativeLayout like this:

((RelativeLayout) findViewById(R.id.container)).addView(myView);

And this is the layout file that I am using:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <RelativeLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Test"
        android:layout_below="@+id/container"/>

</RelativeLayout>

The problem is that the TextView is at the top of the screen instead of being below the RelativeLayout (with the @+id/container id). As it will be without the android:layout_below property.

It behaves like my custom view (MyView) does not set its dimensions. I tried to use the setLayoutParams() but it did not change anything.


Solution

  • I think the problem is that your container view is inflated and laid out before your custom view is added to it and so gets a height of 0 since it has no content. After you add it to its container, a relayout is forced at which point the container asks the child view to measure itself. Since the height of the container is wrap_content, the child needs to report a specific height at this point. My guess is that your MyView class is not doing this.

    An easy thing to do in order to set the height of your MyView objects is to override and implement the onMeasure() method.