Pertanyaan Tombol dialog dengan teks panjang tidak dibungkus / diperas - tema materi pada android 5.0 lollipop


Saat mengoptimalkan aplikasi untuk tema materi di lollipop, saya mengalami masalah yang mengganggu ini:

Setiap kali ada teks panjang pada tombol dialog, yang tidak sesuai lebar bilah tombol secara keseluruhan, teks tidak dibungkus dalam beberapa baris untuk tombol tersebut seperti pada tema sebelumnya. Sebagai gantinya, tombol-tombol berikut terhimpit dari dialog, menjadi tidak dapat dijangkau (lihat gambar di bawah).

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

Saya telah menghabiskan banyak waktu untuk masalah ini sejauh ini dan satu-satunya topik mengenai itu, yang dapat saya temukan di internet adalah ini: https://code.google.com/p/android/issues/detail?id=78302

Jadi saya menerima saran di sana dan menanyakan pertanyaan ini di sini ..

Apa yang saya coba adalah mencari sumbernya (tombol didefinisikan dengan maxLines = 2) dan mengubah parameter yang berbeda pada buttonBarStyle dan buttonBarButtonStyle tetapi tidak berhasil.

Saya mencari solusi gaya sederhana dan tidak ingin menggunakan pustaka pihak ketiga karena ini.

Semoga ini hanya menjadi masalah emulator? Saya tidak berpikir demikian.

Bantuan sangat dihargai. Terima kasih sebelumnya.

Edit: Untuk menindaklanjuti, lihat jawaban saya sendiri sejak 3 Desember, yang bukan solusi.


32
2017-11-28 11:05


asal


Jawaban:


Ini bisa diperbaiki dengan menggunakan tombol yang ditumpuk alih-alih tombol baris. Berikut solusi saya bagaimana itu bisa dicapai dengan menggunakan lib AppCompat:

Kode         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
        }

Gaya

<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>

Hasil

Stacked Alert Dialog


18
2017-07-10 20:49



Menindaklanjuti - Karena saya tidak dapat memposting lebih dari dua tautan karena reputasi pemula saya, saya harus memposting jawaban untuk pertanyaan saya daripada mengeditnya.

Di bawah ini adalah bagaimana saya mencoba menata tombol menggunakan tombolBarStyle dan tombolBarButtonStyle untuk mencapai peningkatan apa pun - lihat hasilnya di sini: http://s12.postimg.org/uyp0p0e6l/dialog_material_button_fix_tests_1.png

sayangnya itu jelas bukan solusi yang diinginkan.

<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>

14
2017-12-03 21:18



Untuk meringkas topik ini bagi siapa saja yang tertarik:

Tema Materi Android tampaknya memiliki bug dengan rentang-rentang-lebar otomatis di dialog peringatan.

Ketika Anda memiliki misalnya 3 tombol, salah satunya memiliki lebih dari satu kata, tombol positif kemungkinan akan terhimpit keluar dari dialog ke kanan, bukan tombol dengan lebih dari satu kata yang dibungkus dalam beberapa baris, sehingga semua tombol pas di bilah tombol seperti tema dasar / tema holo lakukan.

Sepertinya tidak ada solusi hanya dengan menerapkan perubahan pada buttonBarStyle dan / atau buttonBarButtonStyle, karena gaya mereka tidak membatasi teks tombol yang dibungkus dalam beberapa baris secara default.

Tentu, tombol dialog tema Material memerlukan lebih banyak ruang daripada di tema lain secara umum, karena topi, keberanian, dan pengisi serta latar belakang yang murah hati, tetapi itu bukan sumber masalahnya, itu hanya membuatnya muncul lebih cepat daripada jika gaya itu kurang ruang membutuhkan.

Satu-satunya cara untuk memecahkan masalah ini adalah dengan memberikan judul yang lebih pendek pada tombol Anda, jika Anda tidak ingin bergaya jauh dari tampilan dan nuansa Material (seperti membuat ukuran teks tombol menjadi lebih kecil dan / atau menyetel semuaCap ke false).


6
2017-12-15 11:06



gunakan kode berikut, biarkan tombol pada pengaturan kanan dan vertikal

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) {

            }
        }
    });

3
2018-02-24 08:33



Sol cepat yang tidak dinamis adalah dengan menambahkan \ n untuk memecah string panjang


2
2018-04-15 23:18



Berikut adalah solusi yang saya dapatkan, dengan bantuan jawaban terkait dari Andrey T (https://stackoverflow.com/a/29662638/1317564):

Pertama, Anda membuat metode utilitas yang akan membungkus tombol hanya jika mereka perlu dibungkus:

public static void applyWorkaroundForButtonWidthsTooWide(Button dialogButton) {
        if (dialogButton == null)
            return;
        if (!(dialogButton.getParent() instanceof LinearLayout))
            return;            

        // Workaround for buttons too large in alternate languages.
        final LinearLayout linearLayout = (LinearLayout) dialogButton.getParent();
        linearLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop,
                                       int oldRight, int oldBottom) {
                if (right - left > 0) {
                    final int parentWidth = linearLayout.getWidth();
                    int childrenWidth = 0;
                    for (int i = 0; i < linearLayout.getChildCount(); ++i)
                        childrenWidth += linearLayout.getChildAt(i).getWidth();

                    if (childrenWidth > parentWidth) {
                        // Apply stacked buttons
                        linearLayout.setOrientation(LinearLayout.VERTICAL);
                        linearLayout.setPadding(linearLayout.getPaddingLeft(), 0, linearLayout.getPaddingRight(),
                                linearLayout.getPaddingBottom());
                        for (int i = 0; i < linearLayout.getChildCount(); ++i) {
                            if (linearLayout.getChildAt(i) instanceof Button) {
                                final Button child = (Button) linearLayout.getChildAt(i);
                                child.setGravity(Gravity.END | Gravity.CENTER_VERTICAL);
                                final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) child.getLayoutParams();
                                params.width = LinearLayout.LayoutParams.MATCH_PARENT;
                                params.gravity = Gravity.END;
                                child.setLayoutParams(params);
                            } else if (linearLayout.getChildAt(i) instanceof Space) {
                                linearLayout.removeViewAt(i--);
                            }
                        }
                    }

                    linearLayout.removeOnLayoutChangeListener(this);
                }
            }
        });
    }

Anda dapat menambahkan penyalaan kesalahan tambahan (yaitu mencoba / menangkap) dan menyesuaikan ini lebih lanjut sebagaimana mestinya.

Sekarang, Anda memanggil metode utilitas ini ketika dialog ditampilkan:

dialog.setOnShowListener(new DialogInterface.OnShowListener() {
                @Override
                public void onShow(DialogInterface dialogInterface) {
                    MaterialAlertDialogUtils.applyWorkaroundForButtonWidthsTooWide(dialog.getButton(AlertDialog.BUTTON_POSITIVE));
                }
            });

Ini melakukan trik dan hanya akan membungkus tombol jika diperlukan. Saya telah menggunakannya di mana-mana, karena bahkan dialog dua tombol mungkin perlu dibungkus dalam dialog Jerman dan tiga tombol pasti membutuhkannya dalam banyak bahasa.


2
2017-08-14 02:48