Dialog buttons with long text not wrapping / squeezed out - material theme on android 5.0 lollipop

10,202

Solution 1

To summarize this topic for anyone interested:

Android Material theme seems to have a bug with automatic button-width-span in alert dialogs.

When you have for example 3 buttons, one of which having more than one word, the positive button will likely be squeezed out of the dialog to the right, instead of the button with more than one word being wrapped in multiple lines, so that all buttons fit in the button bar like the basic theme / holo theme are doing.

There don't seem to be solutions solely by applying changes to buttonBarStyle and/or buttonBarButtonStyle, since their styles are not restricting button texts being wrapped in multiple lines by default.

Sure, Material theme dialog buttons require more space than in other themes in general, due to caps, boldness and generous padding and background, but that is not the source of the problem, it just makes it appear sooner than if the styling was less space requiring.

The only way to solve this problem seems to be giving your buttons shorter titles, if you don't want to style away from Material's look and feel (like making the button text size smaller and / or setting allCaps to false).

Solution 2

This could be fixed with using stacked buttons instead of row buttons. Here my workaround how it could be achieved with using AppCompat lib :

Code import android.support.v7.app.AlertDialog;

    AlertDialog.Builder builder;
    builder = new AlertDialog.Builder(context, R.style.StackedAlertDialogStyle);
    builder.setTitle("Title");
    builder.setMessage("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dignissim purus eget gravida mollis. Integer in auctor turpis. Morbi auctor, diam eget vestibulum congue, quam arcu pulvinar dui, blandit egestas erat enim non ligula." +
            " Nunc quis laoreet libero. Aliquam consectetur nibh eu arcu eleifend efficitur.");
    builder.setPositiveButton("Positive Button", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
        }
    });
    builder.setNeutralButton("Neutral Button", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
        }
    });
    builder.setNegativeButton("Cancel Button", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
        }
    });
    AlertDialog alertDialog = builder.create();
    alertDialog.show();
        try{
            final Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
            LinearLayout linearLayout = (LinearLayout) button.getParent();
            linearLayout.setOrientation(LinearLayout.VERTICAL);
        } catch(Exception ex){
            //ignore it
        }

Style

<style name="StackedAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="buttonBarButtonStyle">@style/StackedButtonBarButtonStyle</item>
</style>

<style name="StackedButtonBarButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
    <item name="android:layout_gravity">right</item>
</style>

Result

Stacked Alert Dialog

Solution 3

Following up - Since I'm not able to post more than two links due to my beginners reputation, I have to post an answer to my question instead of editing it.

Below is how I tried to style the buttons using buttonBarStyle and buttonBarButtonStyle to achieve any improvement - see the results here: http://s12.postimg.org/uyp0p0e6l/dialog_material_button_fix_tests_1.png

unfortunately those are obviously not desirable solutions.

<resources>
    <style name="AppBaseTheme" parent="android:Theme.Material.Light">
        <!-- AlertDialog Style override in order to try to fix non line breaking buttons -->
        <item name="android:alertDialogTheme">@style/CustomAlertDialogStyle</item>
    </style>  

    <style name="CustomAlertDialogStyle" parent="android:Theme.Material.Light.Dialog.Alert">
        <item name="android:buttonBarButtonStyle">@style/CustomButtonBarButtonStyle</item>
        <item name="android:buttonBarStyle">@style/CustomButtonBarStyle</item>
    </style>

    <style name="CustomButtonBarStyle" parent="@android:style/Widget.Material.Light.ButtonBar.AlertDialog">
        <!-- Making sure, the button bar uses parent width and is not restricted in height -->
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:height">@null</item>
        <item name="android:minHeight">@null</item>
    </style>

    <style name="CustomButtonBarButtonStyle" parent="@android:style/Widget.Material.Light.Button.Borderless.Colored">
        <!-- Setting the weight as follows should result in equally wide buttons filling the alert dialog width,
            but instead they span further out of the dialog, breaking in multiple lines though -->
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_weight">1</item>
        <!-- setting a fixed width as follows results in narrow buttons with line breaks, but of course this is not a solution -->
        <!-- <item name="android:width">100dp</item> -->
    </style>

</resources>

Solution 4

use following code, let buttons on the right and vertical arrangement

alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialog) {
            try {
                LinearLayout linearLayout = (LinearLayout) alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).getParent();
                if (linearLayout != null) {
                    linearLayout.setOrientation(LinearLayout.VERTICAL);
                    linearLayout.setGravity(Gravity.RIGHT);
                }
            } catch (Exception ignored) {

            }
        }
    });

Solution 5

A quick soln that is not dynamic is to add \n to break the long string up

Share:
10,202
sec_aw
Author by

sec_aw

Updated on June 12, 2022

Comments

  • sec_aw
    sec_aw about 2 years

    While optimizing an app for material theme on lollipop, I'm encountering this annoying problem:

    Whenever there is long text on dialog buttons, that doesn't fit the button bar width in total, the text isn't wrapped in multiple lines for those buttons as in previous themes. Instead the following buttons get squeezed out of the dialog, being unreachable (see image below).

    Screenshot: http://s29.postimg.org/3vqp884cn/dialogs_light_holo_material.png

    I've spent a lot of time on this problem so far and the only topic regarding it, that I could find on the internet is this: https://code.google.com/p/android/issues/detail?id=78302

    So I'm taking the advice there and ask this question here..

    What I've tried is looking into the source (buttons are defined with maxLines = 2) and changing different parameters on buttonBarStyle and buttonBarButtonStyle but with no success.

    I'm looking for a simple style-solution and do not want to use third party libraries because of this.

    May this only be an emulator problem? I don't think so.

    Help is very much appreciated. Thanks in advance.

    Edit: To follow up, see my own answer from Dec 3, which is not a solution.

  • Mus
    Mus over 9 years
    Since the text is forced to allCaps on Material, it is taking more space and causing line breaks to be added. I know it's not elegant, but try shortening the button labels or reducing the text size of the dialog buttons. Also, gave you some reps, SO can be annoying when you are just starting out :)
  • sec_aw
    sec_aw over 9 years
    @Mus - many thanks for the reps. It's clear, that Buttons on Material take more space due to caps, boldness and generous padding and background. But they still should behave naturally like in Holo (widening when nessecary and possible, line-breaking when absolutely nessecary) and not just disappear.
  • sec_aw
    sec_aw over 9 years
    To me this actually looks like an Android / Material theme bug. I probably have to end up with radically shortening just a couple of button texts as Mus also mentioned, if I don't want to style away from Material's look and feel. Too bad, e.g. I like a button text like 'do not show again' much better than just 'hide' or the like, which just is not as clear.
  • Mus
    Mus over 9 years
    No problem, you can use a checkbox for 'do not show again'
  • ashishb
    ashishb almost 9 years
    That does not always work, some languages have inherently long translations for even simple English works like OK, Continue etc.
  • Oliv
    Oliv over 8 years
    This will look bad on tablet, where there is enough space
  • Dan Chaltiel
    Dan Chaltiel almost 7 years
    This is working great, but the empty catch make me cringe a little
  • Dan Chaltiel
    Dan Chaltiel almost 7 years
    Works great but only the bottom button is right aligned.
  • Andrey T
    Andrey T almost 7 years
    @dan-chaltiel The empty catch required to prevent a crash in case if some manufactures would change default layout of alert dialog to RelativeLayout for example
  • Sakiboy
    Sakiboy almost 4 years
    What are the parent styles to inherit from if you have to target OS versions less than 21, I receive an error saying that the style is only available in API 21 when using something like: "@android:style/Widget.Material.Light.Button.Borderless.Colo‌​red” as the parent style.