0

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.

desertnaut
  • 57,590
  • 26
  • 140
  • 166
lOOFv
  • 3
  • 2

2 Answers2

0

Probably your dialog has no parent. Therefore the match_parent of the ConstraintLayout does not work. So the dialog is limited only to the elements that have wrap_content set. If you display the whole thing in a normal fragment that has an activity, it works. Therefore I would try to use a DialogFragment. There it should work without problems. Besides, it looks even nicer.

Documentation for this: https://developer.android.com/guide/fragments/dialogs

desertnaut
  • 57,590
  • 26
  • 140
  • 166
WannaBe
  • 81
  • 7
  • Thank you for your reply! I think it should have a parent, it is created and displayed within an activity that itself has a constraintlayout. Like this: View popup = inflater.inflate(R.layout.my_custom_layout, null); final AlertDialog alertDialog = new AlertDialog.Builder(this).create(); alertDialog.setCancelable(false); alertDialog.setView(popup); alertDialog.show(); – lOOFv Sep 21 '22 at 13:56
  • It seems like there is a bug in constraint layout or layout height cannot be applied to constraint layout in a scroll view but you can use minimum height attribute in constraint layout. Try so set min height: android:minHeight="500dp" and maybe a layout height: android:layout_height="500dp" – WannaBe Sep 22 '22 at 05:00
  • Even better would be to put a ContraintLayout outside the scroll view. look here: https://stackoverflow.com/a/44843684/13359215 – WannaBe Sep 22 '22 at 05:03
  • Hmm interesting. The problem is I don't want to set a fixed dp value for height, I want it to scale for small 800x480 devices as well as the newer high DPI devices. But I will try adding an inner constraint layout like the thread you linked, thanks! I'll report back how that goes. – lOOFv Sep 22 '22 at 08:08
  • Same problem there unfortunately. I tried the other answer in my thread as well, using a scrollable text view instead of a scrollView, but even then it still just disappears. – lOOFv Sep 22 '22 at 08:16
  • look to my new answer! :) And please dont forget to upvote my answers – WannaBe Sep 22 '22 at 09:09
0

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;
         }
    });
WannaBe
  • 81
  • 7
  • Thanks for your reply! Match parent match parent doesn't work either unfortunately, as that makes the text appear behind the title and button if the text is larger than the full screen. I will look into popupwindow and see if that works! – lOOFv Sep 22 '22 at 13:45
  • PopupWindow actually works, thank you! Though it appears behind a previous popup, but that is due to my implementation. To me, I think it should work with alertDialog as well but there seems to be some sort of bug in this case. Big thanks for your help! – lOOFv Sep 22 '22 at 13:51