Search code examples
androidtextviewscrollviewandroid-constraintlayout

ScrollView containing a TextView disappears in ConstraintLayout when height is set to 0dp


I am trying to create a custom alertDialog with a ConstraintLayout, containing a title, scrollview with a textview, and a button at the bottom.

I want the scrollview to grow/shrink dynamically and fill the available space between the title and the button, which works in the preview, but when running the actual app, the scrollview and textview seem to actually shrink to 0dp and disappear (as I understand it, 0dp with fillViewport should grow to fit the available space according to the constraints.

Preview

Actual app

layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/white">
    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="A title"
        android:textSize="20dp"
        android:gravity="start"
        android:textColor="#000000"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
    <ScrollView
        android:id="@+id/svBody"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:fillViewport="true"
        app:layout_constraintTop_toBottomOf="@id/tvTitle"
        app:layout_constraintBottom_toTopOf="@id/btnClose"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        >
        <TextView
            android:id="@+id/tvBody"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="AA text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long. text that is really long."
            android:textSize="16dp"
            android:textColor="#000000"
            />
    </ScrollView>
    <Button
        android:id="@+id/btnClose"
        android:layout_width="100dp"
        android:layout_height="40dp"
        android:text="close"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_margin="5dp"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

Could this be caused by some conflict with the constraints of the view that is later responsible for rendering this custom alertDialog? Or am I missing something else?

I can of course solve it by setting a fixed size on the scrollView, but then it looks small on bigger screens so I'm hoping for a dynamic solution.


Solution

  • So I fixed it, if you make the values match_parent, instead of 0dp it works:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:background="@color/white">
        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="A title"
            android:textSize="20dp"
            android:gravity="start"
            android:textColor="#000000"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />
        <ScrollView
            android:id="@+id/svBody"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true"
            app:layout_constraintTop_toBottomOf="@id/tvTitle"
            app:layout_constraintBottom_toTopOf="@id/btnClose"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            >
            <TextView
                android:id="@+id/tvBody"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="AA text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long.A text that is really long. text that is really long."
                android:textSize="16dp"
                android:textColor="#000000"
                />
        </ScrollView>
        <Button
            android:id="@+id/btnClose"
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:text="close"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_margin="5dp"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    Other option, Use PopupWindow instead of AlertDialog (the popup view you can infalte normally, as you did before):

        int width = LinearLayout.LayoutParams.MATCH_PARENT;
        int height = LinearLayout.LayoutParams.MATCH_PARENT;
        boolean focusable = true; // lets taps outside the popup also dismiss it
        final PopupWindow popupWindow = new PopupWindow(popupView, width, height, focusable);
            
        // show the popup window
        // which view you pass in doesn't matter, it is only used for the window tolken
    
    popupWindow.showAtLocation(getWindow().getDecorView().findViewById(android.R.id.content), Gravity.CENTER, 0, 0);
            
        // dismiss the popup window when touched
        popupView.setOnTouchListener(new View.OnTouchListener() {
             @Override
             public boolean onTouch(View v, MotionEvent event) {
                  popupWindow.dismiss();
                  return true;
             }
        });