如何正确更改材质设计的对话框正面按钮背景

Posted

技术标签:

【中文标题】如何正确更改材质设计的对话框正面按钮背景【英文标题】:How to change material designed dialog positive button background correctly 【发布时间】:2016-08-26 20:07:44 【问题描述】:

我有以下对话框

它是使用以下代码创建的

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

因此,我们希望将用户的注意力吸引到正面按钮 (RATE 5 STARS)。我们倾向于

按钮文本颜色为白色 按钮背景颜色为蓝色

我们在返回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);
         
     );

我们得到以下结果

它没有达到我们想要的效果

正按钮丢失了其默认边距和内边距信息。 按下正面按钮的波纹选择器行为消失了。

这是在按下普通按钮的情况下进行比较的方式。在我们的例子中,当我们按下正面按钮时,视觉上没有变化。

是否有适当的方法来更改材质设计的对话框正按钮背景,而不会丢失其默认边距、填充和波纹选择器行为?

【问题讨论】:

为了实现这样的功能,你应该使用自定义对话框而不是使用 AlertDialog 通过创建自定义布局来膨胀。 创建一个自定义布局并在您的对话框中填充它... @Cheok Yan Cheng 在下面看到我的更新答案。 【参考方案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();

现在创建 Layout XML dialog_demo.xml 并创建您的 UI/设计。这是我为演示目的创建的示例:

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

<TextView
    android:id="@+id/textview1"
    android:layout_
    android:layout_
    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_
    android:layout_
    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_
    android:layout_
    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_
    android:layout_
    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_
    android:layout_below="@+id/textview4"
    android:layout_
    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_
    android:layout_below="@+id/textview4"
    android:layout_
    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_
    android:layout_below="@+id/textview4"
    android:layout_
    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() :) 这是上面代码的截图。

请注意,strings.xmlcolors.xml 使用的文本和颜色。你可以自己定义。

【讨论】:

@Cheok Yan Cheng 你看到我的回答了吗? 这并不能解决问题。您的“RATE 5 STARS”按钮如何与“NO”按钮具有相同的边距、填充和选择器行为? @CheokYanCheng 你想要什么给我一些规格,以便我可以帮助你。 @CheokYanCheng 如果你想要ripple effect 然后create 可绘制文件并将其设置为Button 背景并在可绘制文件中设置ripple effect【参考方案2】:

通过引用https://***.com/a/27505229/72437,我能够更改正按钮的背景,而不会影响其默认边距、填充和选择器行为。

请注意,我们不使用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://***.com/questions/28484369/what-should-be-the-color-of-the-ripple-colorprimary-or-coloraccent-material-d -->
<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 及更高版本。

【讨论】:

【参考方案3】:
              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>

并在您的样式中添加上述样式

【讨论】:

以上是关于如何正确更改材质设计的对话框正面按钮背景的主要内容,如果未能解决你的问题,请参考以下文章

对话框不显示正面和负面按钮

CSS中的滚动材质设计对话框

如何根据对话框组件中的取消和是按钮更新父组件的材质幻灯片切换值?

AngularJS 材质对话框在 Mac Safari 中无法正确显示

用Word制作表格,如何更改表格背景色

如何更改 MFC/VC++ 对话框应用程序中按钮的前景色(即文本或标题)