0

I'm trying to make a help popup. Since the help tips will be different according to which screen you click the help button from, I want to put the text inside a scroll just in case. My layout looks like this:

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

<TextView
    android:id="@+id/helpPopupTitle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="10dp"
    android:layout_marginTop="20dp"
    android:layout_marginEnd="10dp"
    android:gravity="center"
    android:text="@string/help_popup_title"
    android:textColor="?attr/colorOnBackground"
    android:textSize="24sp"
    android:textStyle="bold" />

<ScrollView
    android:id="@+id/scroll"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_marginStart="10dp"
    android:layout_marginTop="20dp"
    android:layout_marginEnd="10dp"
    android:layout_weight="1"
    android:fillViewport="true">

    <TextView
        android:id="@+id/helpTips"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/help_tips"
        android:textSize="20sp" />

</ScrollView>

<Button
    android:id="@+id/footerButton"
    style="@style/RoundedButton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:layout_marginStart="10dp"
    android:layout_marginTop="20dp"
    android:layout_marginEnd="10dp"
    android:layout_marginBottom="20dp"
    android:text="@string/footer_button_text" />

It's basically a title, the scroll, and a button. My problem is, when the popup shows up, the scroll is just as tall as the text inside of it.

This is how it looks

This is how I build the dialog:

val dialogView = LayoutInflater.from(this).inflate(R.layout.help_popup, null)
        val dialogBuilder = AlertDialog.Builder(this).setView(dialogView)
        dialogView.findViewById<TextView>(R.id.helpPopupTitle).setText(R.string.help_popup_title)
        dialogView.findViewById<TextView>(R.id.helpTips).setText(R.string.help_tips)
        val dialog = dialogBuilder.create()
        dialog.setCanceledOnTouchOutside(true)
        dialogView.findViewById<Button>(R.id.footerButton).setOnClickListener {
            dialog.dismiss()
        }
        dialog.show()
        val displayMetrics = DisplayMetrics()
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            val display = display
            display?.getRealMetrics(displayMetrics)
        } else {
            @Suppress("DEPRECATION")
            val display = windowManager.defaultDisplay
            @Suppress("DEPRECATION")
            display.getMetrics(displayMetrics)
        }

        val width = displayMetrics.widthPixels
        val height = displayMetrics.heightPixels

        val popupWidth = width * 0.9
        val popupHeight = height * 0.85
        dialog.window!!.setLayout(popupWidth.toInt(), popupHeight.toInt())

It is really messy, but so far it works since what I want is a popup that covers most of the screen but not entirely. I've looked in other threads but most just say "just put android:fillViewport="true" and the scroll will fill the parent" but it doesn't work for me, maybe I messed up something while building the popup. Any help?

EDIT: After trying the answer provided by gioravered the weight is actually working and the scroll fills the parent. The only problem is that now the layout is slightly offcentered.

Popup after the edit

  • No need to wrap a TextView with a ScrollView. TextView can be scrollable. Check https://stackoverflow.com/a/3256305/2649154 – gioravered Aug 30 '21 at 06:44
  • Oh, I didn't know. I'll try it out to see if it works as I want it to. – Javier Takano Aug 30 '21 at 07:04
  • Well, I see that the ScrollView is unnecessary, but it still doesnt expand to fill the parent, even after adding layout_weight="1" to the TextView, it is still as small as in the image I posted. I feel that it may be because of how I'm building the dialog, but I don't know what the problem could be. – Javier Takano Sep 01 '21 at 04:01

1 Answers1

1

Keep your LinearLayout, but add an ID for the root view (mainLayout):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/mainLayout"
    android:orientation="vertical">

    <TextView
        android:id="@+id/helpPopupTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="10dp"
        android:gravity="center"
        android:text="@string/help_popup_title"
        android:textColor="?attr/colorOnBackground"
        android:textSize="24sp"
        android:textStyle="bold" />

    <ScrollView
        android:id="@+id/scroll"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="10dp"
        android:layout_weight="1"
        android:fillViewport="true">

        <TextView
            android:id="@+id/helpTips"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/help_tips"
            android:textSize="20sp" />

    </ScrollView>

    <Button
        android:id="@+id/footerButton"
        style="@style/RoundedButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginStart="10dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="10dp"
        android:layout_marginBottom="20dp"
        android:text="@string/footer_button_text" />
</LinearLayout>

What you did was changing the size of the dialog window. Instead, let's change the size of the Layout itself.

val dialogView = LayoutInflater.from(this).inflate(R.layout.popup, null)
        val dialogBuilder = AlertDialog.Builder(this).setView(dialogView)
        val dialog = dialogBuilder.create()
        dialog.setCanceledOnTouchOutside(true)
        dialogView.findViewById<Button>(R.id.footerButton).setOnClickListener {
            dialog.dismiss()
        }

        dialog.show()
        val displayMetrics = DisplayMetrics()
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            val display = display
            display?.getRealMetrics(displayMetrics)
        } else {
            @Suppress("DEPRECATION")
            val display = windowManager.defaultDisplay
            @Suppress("DEPRECATION")
            display.getMetrics(displayMetrics)
        }

        val screenWidth = displayMetrics.widthPixels
        val screenHeight = displayMetrics.heightPixels

        val popupWidth = screenWidth * 0.9
        val popupHeight = screenHeight * 0.85

        val mainLayout = dialogView.findViewById<LinearLayout>(R.id.mainLayout)
        val params = (mainLayout.layoutParams as? FrameLayout.LayoutParams)?.apply {
            width = popupWidth.toInt()
            height = popupHeight.toInt()
            gravity = Gravity.CENTER;
        }

        mainLayout.layoutParams = params

The change is this line:

dialogView.findViewById<LinearLayout>(R.id.mainLayout).layoutParams = 

Since the layout is the parent layout it will determine the size of the dialog.

gioravered
  • 1,758
  • 3
  • 19
  • 30
  • This works, although it feels kinda weird to set values manually like that. I'll try it in multiple screen sizes to check if there's any problem but so far it works correctly. Thanks! – Javier Takano Sep 02 '21 at 06:15
  • 1
    See my edits. I've used your LinearLayout, but changed the way you set the size. – gioravered Sep 02 '21 at 08:08
  • If this answers your issue then please "accept" the answer. – gioravered Sep 02 '21 at 08:42
  • Thanks, it works great! (I haven't seen any case so far where it looks wrong). Could you explain to me why it didn't work the way I was doing it before? I can't see why it would behave differently (I'm really confused about why the weight was being ignored before) – Javier Takano Sep 02 '21 at 09:49
  • I'm not 100% sure but I think that changing the window size (of the dialog) is not causing a re-layout. The dialog opens with default size (Alert Dialog) and the layout (xml) was done according to this size. Then you changed the window size and the layout remained the same. – gioravered Sep 02 '21 at 09:52
  • I added an edit because I noticed the layout is now slightly offcentered, for some reason – Javier Takano Sep 02 '21 at 09:58
  • I've edited the answer to address this issue. – gioravered Sep 02 '21 at 10:21