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

3
  • No need to wrap a TextView with a ScrollView. TextView can be scrollable. Check stackoverflow.com/a/3256305/2649154 Commented Aug 30, 2021 at 6:44
  • Oh, I didn't know. I'll try it out to see if it works as I want it to. Commented Aug 30, 2021 at 7: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. Commented Sep 1, 2021 at 4:01

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

7 Comments

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!
See my edits. I've used your LinearLayout, but changed the way you set the size.
If this answers your issue then please "accept" the answer.
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)
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.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.