Search code examples
androidandroid-relativelayout

Android: stretch layout above another


I create layout (ContentLayout) with wrap_content. And I want to show loading layout (LoadingLayout) same size as ContentLayout above it. Something like this:

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

    <LinearLayout.
            android:id="@+id/ContentLayout"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            ...

    </LinearLayout>


    <RelativeLayout
            android:id="@+id/LoadingLayout"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">

            ...

    </RelativeLayout>

</RelativeLayout>

But when I want set LoadingLayout size in onMeasure, it will be set to right size only in second chance. Works only something like this:

Activity

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) loadingLayout.getLayoutParams();
    params.height = getMeasuredHeight();
    loadingLayout.setLayoutParams(params);

    super.onMeasure(widthMeasureSpec, heightMeasureSpec); // android realignment hack
}

I think this is a hack. Do you have a better solution?


Solution

  • If I understood correctly, you need LoadingLayout to keep width of ContentLayout

    <RelativeLayout
        android:id="@+id/LoadingLayout"
        android:layout_alignLeft="@id/ContentLayout"
        android:layout_alignRight="@id/ContentLayout"
        ....>
    ....
    </RelativeLayout>
    

    Edit: Below is one way for the height

    You can add a one time listener when global refresh happens. Then all sizes will be available.

    // in your activity
    @Override
    protected void onCreate(Bundle state) {
        final View loading = findViewById(R.id.LoadingLayout);
        final View content = findViewById(R.id.ContentLayout);
        content.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                content.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                loading.getLayoutParams().height = content.getHeight();
                loading.onRequestLayout();
                loading.invalidate();
            }
        }
     }