如何正确更改Material Design对话框的积极按钮背景

5
我有以下对话框:

enter image description here

这是使用以下代码创建的:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Random random = new Random();
    // 0 or 1.
    final int value = random.nextInt(2);
    final int title = R.string.we_love_you_0; 
    final int content = R.string.rate_us_with_5_stars_review_0;

    final AlertDialog dialog = new AlertDialog.Builder(this.getActivity())
    .setTitle(title)
    .setMessage(content)
    // Add action buttons
    .setPositiveButton(R.string.rate_5_stars, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
        }
    })
    .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
        }
    })
    .setNeutralButton(R.string.later, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
        }
    })
    .create();

    dialog.setCanceledOnTouchOutside(false);

    return dialog;
}

为了吸引用户关注积极的按钮(五星好评),我们倾向于:

  • 使用白色按钮文本颜色
  • 使用蓝色按钮背景颜色

我们在返回dialog之前添加以下代码:

    dialog.setOnShowListener(new DialogInterface.OnShowListener() {
         @Override
         public void onShow(DialogInterface d) {
             Button positiveButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
             positiveButton.setTextColor(rateAppDialogPositiveButtonTextColor);
             positiveButton.setBackgroundColor(rateAppDialogPositiveButtonBackgroundColor);
         }
     });

我们得到了以下结果:

enter image description here

但这并不是我们想要的,因为:

  • 积极按钮失去了其默认的边距和填充信息。
  • 积极按钮按下时的波纹选择器行为消失了。

这是与正常按钮按下时的比较。在我们的情况下,当我们按下积极按钮时,没有任何视觉变化。

enter image description here

有没有一种适当的方法可以更改材料设计对话框积极按钮的背景,而不会失去其默认的边距、填充和波纹选择器行为?


为了实现这样的功能,您应该使用自定义对话框,而不是通过创建自定义布局来充气使用AlertDialog。 - Jaimin Modi
创建一个自定义布局并在对话框中填充它... - Iamat8
@Cheok Yan Cheng,请查看我下面更新的答案。 - user5248371
3个回答

1
创建自定义对话框,以便您可以给它添加颜色。
只需简单地创建一个对话框方法,类似于在您的Java类中的任何位置:
public void openDialog() {
    final Dialog dialog = new Dialog(context); // Context, this, etc.
    dialog.setContentView(R.layout.dialog_demo);
    dialog.setTitle(R.string.dialog_title);
    dialog.show();
}

现在创建布局XML文件 dialog_demo.xml 并设计你的UI。这是我为演示目的创建的一个示例:
<?xml version="1.0" encoding="utf-8"?>

<TextView
    android:id="@+id/textview1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textColor="#000000"
    android:text="We love you!"
    android:textStyle="bold"
    android:layout_marginLeft="10dp"
    android:textSize="16sp"/>
<TextView
    android:id="@+id/textview2"
    android:layout_below="@+id/textview1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#000000"
    android:text="Can we assume that the feeling's mutual ?"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="30dp"
    android:textSize="16sp"/>
<TextView
    android:id="@+id/textview3"
    android:layout_below="@+id/textview2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#000000"
    android:text="If you've been enjoying our app, we'd really appreciate it if you could leave us a nice revire in the market."
    android:layout_marginLeft="20dp"
    android:layout_marginTop="10dp"
    android:layout_marginRight="30dp"
    android:textSize="16sp"/>

<TextView
    android:id="@+id/textview4"
    android:layout_below="@+id/textview3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#000000"
    android:text="It'll really help us grow ?"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="30dp"
    android:layout_marginTop="10dp"
    android:textSize="16sp"/>

<Button
    android:id="@+id/dialog_later"
    android:layout_width="wrap_content"
    android:layout_below="@+id/textview4"
    android:layout_height="wrap_content"
    android:textColor="#0072BA"
    android:textSize="14sp"
    android:textStyle="bold"
    android:layout_marginTop="10dp"
    android:background="@android:color/transparent"
    android:text="LATER"/>

<Button
    android:id="@+id/dialog_no"
    android:layout_width="wrap_content"
    android:layout_below="@+id/textview4"
    android:layout_height="wrap_content"
    android:textColor="#0072BA"
    android:textSize="14sp"
    android:textStyle="bold"
    android:layout_marginTop="10dp"
   android:layout_marginLeft="60dp"
    android:background="@android:color/transparent"
    android:text="NO"/>

<Button
    android:id="@+id/dialog_ratestar"
    android:layout_width="wrap_content"
    android:layout_below="@+id/textview4"
    android:layout_height="wrap_content"
    android:textColor="#FFFFFF"
    android:textSize="14sp"
    android:textStyle="bold"
    android:layout_marginTop="10dp"
    android:layout_marginLeft="100dp"
    android:background="#0072BA"
    android:layout_alignParentEnd="true"
    android:layout_alignParentRight="true"
    android:layout_marginRight="10dp"
    android:padding="5dp"
    android:text="RATE 5 STARS *"/>

现在你可以从任何地方调用openDialog() :) 这是上述代码的截图。

enter image description here

请注意,文本和颜色来自于 strings.xmlcolors.xml。您可以定义自己的内容。

@Cheok Yan Cheng,你看到我的回答了吗? - user5248371
这并没有解决问题。你的“给5星评分”按钮怎么和“否”按钮具有相同的边距、内边距和选择器行为? - Cheok Yan Cheng
@CheokYanCheng,你想要什么?给我一些具体的规格,这样我就可以帮助你了。 - user5248371
@CheokYanCheng 如果你想要"水波纹效果",那就创建一个可绘制文件,并将其设置为按钮的背景,在可绘制文件中设置"水波纹效果"。 - user5248371

1
通过参考https://dev59.com/R18d5IYBdhLWcg3wt0EQ#27505229,我成功地改变了正按钮的背景颜色,而不影响其默认的边距、填充和选择器行为。
请注意,我们不使用colorButtonNormal,因为在Java代码中无法更改按钮样式。

dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Default insets (outer padding) around buttons -->
    <dimen name="button_inset_vertical_material">6dp</dimen>
    <dimen name="button_inset_horizontal_material">@dimen/control_inset_material</dimen>
    <!-- Default inner padding within buttons -->
    <dimen name="button_padding_vertical_material">@dimen/control_padding_material</dimen>
    <dimen name="button_padding_horizontal_material">8dp</dimen>
    <!-- Default insets (outer padding) around controls -->
    <dimen name="control_inset_material">4dp</dimen>
    <!-- Default inner padding within controls -->
    <dimen name="control_padding_material">4dp</dimen>
    <!-- Default rounded corner for controls -->
    <dimen name="control_corner_material">2dp</dimen>
</resources>

colors.xml

<color name="rate_app_dialog_positive_button_text_color_material_light">#ffffffff</color>
<color name="rate_app_dialog_positive_button_background_color_material_light">#ff0091ea</color>
<color name="rate_app_dialog_positive_button_pressed_background_color_material_light">#7f0091ea</color>

attrs.xml

<attr name="rateAppDialogPositiveButtonTextColor" format="color" />
<attr name="rateAppDialogPositiveButtonSelector" format="color" />

drawable-v21/rate_app_dialog_positive_button_selector_for_ripple_material_light.xml

<?xml version="1.0" encoding="utf-8"?>

<!-- Used as the canonical button shape. -->

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetLeft="@dimen/button_inset_horizontal_material"
    android:insetTop="@dimen/button_inset_vertical_material"
    android:insetRight="@dimen/button_inset_horizontal_material"
    android:insetBottom="@dimen/button_inset_vertical_material">
    <shape android:shape="rectangle"
        android:tint="@color/rate_app_dialog_positive_button_background_color_material_light">
        <corners android:radius="@dimen/control_corner_material" />
        <solid android:color="#ffffffff" />
        <padding android:left="@dimen/button_padding_horizontal_material"
            android:top="@dimen/button_padding_vertical_material"
            android:right="@dimen/button_padding_horizontal_material"
            android:bottom="@dimen/button_padding_vertical_material" />
    </shape>
</inset>

drawable-v21/rate_app_dialog_positive_button_selector_material_light.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- https://dev59.com/nV4b5IYBdhLWcg3w9Fyr -->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/ripple_material_dark">
    <!-- @color/ripple_material_light -->
    <!-- @color/ripple_material_dark -->
    <item android:drawable="@drawable/rate_app_dialog_positive_button_selector_for_ripple_material_light" />
</ripple>

drawable/rate_app_dialog_positive_button_selector_material_light.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- pressed state -->
    <item android:state_pressed="true">
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/rate_app_dialog_positive_button_pressed_background_color_material_light" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>

    <!-- focused state -->
    <item android:state_focused="true">
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/rate_app_dialog_positive_button_pressed_background_color_material_light" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>

    <!-- normal state -->
    <item>
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/rate_app_dialog_positive_button_background_color_material_light" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
</selector>

themes.xml

    <item name="rateAppDialogPositiveButtonTextColor">@color/rate_app_dialog_positive_button_text_color_material_light</item>
    <item name="rateAppDialogPositiveButtonSelector">@drawable/rate_app_dialog_positive_button_selector_material_light</item>

RateAppDialogFragment.java

    TypedValue typedValue = new TypedValue();
    Resources.Theme theme = this.getContext().getTheme();
    theme.resolveAttribute(R.attr.rateAppDialogPositiveButtonTextColor, typedValue, true);
    final int rateAppDialogPositiveButtonTextColor = typedValue.data;
    theme.resolveAttribute(R.attr.rateAppDialogPositiveButtonSelector, typedValue, true);
    final int rateAppDialogPositiveButtonSelectorResourceId = typedValue.resourceId;

    dialog.setOnShowListener(new DialogInterface.OnShowListener() {
         @Override
         public void onShow(DialogInterface d) {
             Button positiveButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
             positiveButton.setTextColor(rateAppDialogPositiveButtonTextColor);
             positiveButton.setBackgroundResource(rateAppDialogPositiveButtonSelectorResourceId);
         }
     });

这对于 Android 4 及以上版本非常有效。

enter image description here


0
              MaterialAlertDialogBuilder(it, R.style.MaterialDialog)
                    .setTitle(R.string.title_logout)
                    .setMessage(R.string.msg_logout)
                    .setNegativeButton("Cancel", null)
                    .setPositiveButton("Ok") { _, _ ->
                        vm.logout()
                        val intent = Intent(context, AuthActivity::class.java)
                        startActivity(intent)
                        activity?.finish()
                    }
                    .create()
                    .show()

使用上述代码创建对话框。
<style name="MaterialDialog" parent="Theme.MaterialComponents.Light.Dialog">
    <item name="android:windowNoTitle">true</item>
    <item name="android:buttonBarPositiveButtonStyle">@style/MaterialDialog.ButtonStyle</item>
    <item name="android:buttonBarNegativeButtonStyle">@style/MaterialDialog.ButtonStyle</item>
    <item name="android:textColorPrimary">@color/black</item>
    <item name="colorPrimary">@color/colorAccent</item>
    <item name="android:background">@color/white</item>
</style>




<style name="MaterialDialog.ButtonStyle">
    <item name="android:background">@color/white</item>
</style>

在你的样式表中添加上述样式


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接