Android:AlertDialog Button 不接受样式

Posted

技术标签:

【中文标题】Android:AlertDialog Button 不接受样式【英文标题】:Android: AlertDialog Button not accepting style 【发布时间】:2012-03-11 03:53:15 【问题描述】:

我已经为我的警报对话框设置了一个样式,并且该样式在对话框的 [大部分] 上显示没有问题,唯一的问题是按钮。

手机是运行 SenseUI 的 HTC Evo,AlertDialog 按钮继续通过 SenseUI 主题进行皮肤设置。我尝试将我的应用程序样式 (rtg_style) 更改为 Theme.Dialog 而不是 Theme.Light.NoTitleBar 的子项,并且活动按钮的样式继续正确,但 AlertDialogs 的样式也继续不正确。我试图避免编写完全自定义的 AlertDialog 替换,我还能做什么?

样式.xml:

<style name="rtg_style" parent="@android:style/Theme.Light.NoTitleBar">
    <item name="android:windowBackground">@drawable/bluebg</item>
    <item name="android:buttonStyle">@style/rtg_Button</item>
    <item name="android:listViewStyle">@style/rtg_ListView</item>
    <item name="android:expandableListViewStyle">@style/rtg_ExpandableListView</item>
</style>

<style name="rtg_AlertDialog" parent="@style/rtg_style"> <!-- parent="@android:style/Theme.Dialog"> --> 
    <item name="android:buttonStyle">@style/rtg_Button</item>
    <item name="android:listViewStyle">@style/rtg_ListView</item>
    <item name="android:alertDialogStyle">@style/dialog</item>
</style>

<style name="rtg_Button" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/button</item>
    <item name="android:textColor">#ffffff</item>
    <item name="android:textSize">15sp</item>
    <item name="android:textStyle">bold</item>
    <item name="android:height">40dp</item>
</style>

<style name="rtg_ListView" parent="@android:style/Widget.ListView">
    <item name="android:listSelector">@drawable/listview</item>
</style>

<style name="rtg_ExpandableListView" parent="@android:style/Widget.ExpandableListView">
    <item name="android:listSelector">@drawable/listview</item>
</style>    

<style name="base">
    <item name="android:padding">10dp</item>
</style>    

<style name="title" parent="@style/base">
      <item name="android:textColor">#FFFFFF</item>
    <item name="android:textSize">16sp</item>
    <item name="android:textStyle">bold</item>
</style>

<style name="body" parent="@style/base">
    <item name="android:textColor">#000000</item>
    <item name="android:textStyle">normal</item>
</style>

<style name="dialog">
    <item name="android:fullDark">@drawable/dialog_body</item>
    <item name="android:topDark">@drawable/dialog_title</item>
    <item name="android:centerDark">@drawable/dialog_body</item>
    <item name="android:bottomDark">@drawable/dialog_footer</item>
    <item name="android:fullBright">@drawable/dialog_body</item>
    <item name="android:centerBright">@drawable/dialog_body</item>
    <item name="android:bottomBright">@drawable/dialog_footer</item>
    <item name="android:bottomMedium">@drawable/dialog_footer</item>
    <item name="android:centerMedium">@drawable/dialog_body</item>
    <item name="android:windowIsFloating">true</item>

</style>

Activity.java:

AlertDialog.Builder ab = new AlertDialog.Builder(new ContextThemeWrapper(OrderSummary.this, R.style.rtg_AlertDialog));
            ab.setTitle("Select a reason");
            String[] reasons = new String[Shared.Reasons_RejectAll.size()];
            for (int i = 0; i < Shared.Reasons_RejectAll.size(); i++)  
                try 
                    reasons[i] = Shared.Reasons_RejectAll.get(i).Name;
                 catch (Exception ex) 
                    ex.printStackTrace();
                
            
            ab.setItems(reasons, new DialogInterface.OnClickListener() 
                @Override
                public void onClick(DialogInterface dialog, int which) 
                    rejectReason = Shared.Reasons_RejectAll.get(which).Name;
                    for (int i = 0; i <= r.ItemList.length; i++)
                        r.ItemList[index].item.get(i).setStatus(eItemStatus.REJECTED);
                        r.ItemList[index].item.get(i).setRejectReason(rejectReason);
                    
                    adapter.notifyDataSetChanged();
                
            ) 
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() 

                @Override
                public void onClick(DialogInterface dialog, int which) 
                    // No additional code required at this time.
                
            );
            //ab.show();

            AlertDialog dialog = ab.create();
            dialog.show();

【问题讨论】:

【参考方案1】:

我刚刚尝试过的东西很有效。您可以使用 getButton(int whichButton) 来提取 Button 的 View 类,然后您可以随心所欲地屠宰它。

在你这样做之前,调用 .show() 函数,否则按钮本身不会被创建,getButton() 命令给你 null,并且 NullPointerExceptions 很糟糕。拿到按钮后,就可以做 .setBackgroundDrawable 和 .setTextColor 之类的 Button/TextView(Button 是 TextView 的扩展)功能。

AlertDialog alert = new AlertDialog.Builder(activity).create();
// configure things here like the title and message
alert.show();

Button button = alert.getButton(AlertDialog.BUTTON_NEGATIVE);
button.setBackgroundResource(R.drawable.negative_button_selector);

如果有人能弄清楚如何在创建新按钮并滑动该按钮的内容之外设置样式/主题,我会全力以赴,因为这样会更好。

摇滚!摇滚吧!

【讨论】:

不错!尽管您无法使用此解决方案设置标题(尤其是分隔线)的样式... 然而,有一点需要考虑——getButton() 将返回null,直到调用show()(这是一个错误)。大多数时候这不是问题,但有时它是 - 例如。使用DialogFragment 时。在这种情况下,解决方法是添加OnShowListener 并在其中调用getButton() 太酷了。我不知道 OnShowListener,可以将它添加到我的技巧包中 还不错吧?这很棒!这正是我想要的。比仅仅为按钮设置样式而编写替换类要简单得多。【参考方案2】:

找到答案了!根据我的研究,alertdialog 上的按钮使用它们自己无法覆盖的布局,因此我最终将 Dialog 子类化并自己构建了一个自定义对话框。

CustomDialog.java:

public class CustomDialog extends Dialog implements OnClickListener 
TextView tvTitle;
TextView tvMessage;
Button btnOK;
ListView listView;
Context context;
ProgressBar prgWait;
ProgressBar prgBar;

public CustomDialog(Context context) 
    super(context, R.style.rtg_DialogActivity);
    setContentView(R.layout.dialog);
    this.context = context;

    // replace the background dim with a background blur effect
    WindowManager.LayoutParams lp = getWindow().getAttributes();
    lp.dimAmount = 0.0f;
    getWindow().setAttributes(lp);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

    tvTitle = (TextView) findViewById(R.id.tvDialogTitle);
    tvMessage = (TextView) findViewById(R.id.tvDialogMessage);
    btnOK = (Button) findViewById(R.id.btnDialog);
    listView = (ListView) findViewById(R.id.lvDialogList);
    prgWait = (ProgressBar) findViewById(R.id.prgDialog);
    prgBar = (ProgressBar) findViewById(R.id.prgDialogBar);


public CustomDialog setTitle(String text) 
    tvTitle.setText(text);      
    return this;


public CustomDialog setMessage(String text) 
    tvMessage.setVisibility(View.VISIBLE);
    tvMessage.setText(text);        
    return this;


public CustomDialog setList(List<String> list, OnItemClickListener l) 
    ArrayAdapter<String> aa = new ArrayAdapter<String>(this.getContext(), android.R.layout.simple_list_item_1, list);
    listView.setVisibility(View.VISIBLE);
    listView.setAdapter(aa);
    listView.setOnItemClickListener(l);         
    return this;


public CustomDialog setList(String[] list, OnItemClickListener l) 
    List<String> lString = new ArrayList<String>();
    for (String s : list)
        lString.add(s);     
    return setList(lString, l);


public CustomDialog setButton(String text, View.OnClickListener l) 
    btnOK.setText(text);
    btnOK.setOnClickListener(l);
    return this;


public CustomDialog setButton(String text) 
    return setButton(text, this);


public CustomDialog isIndeterminate(boolean b) 
    if (b) 
        prgWait.setVisibility(View.VISIBLE);
        btnOK.setVisibility(View.GONE);
     else 
        prgWait.setVisibility(View.GONE);
        btnOK.setVisibility(View.VISIBLE);
    
    return this;


public CustomDialog isProgress(boolean b) 
    if (b) 
        prgBar.setVisibility(View.VISIBLE);
        btnOK.setVisibility(View.GONE);
     else 
        prgBar.setVisibility(View.GONE);
        btnOK.setVisibility(View.VISIBLE);
    
    return this;


public CustomDialog setProgressMax(int max) 
    prgBar.setMax(max);
    return this;


public CustomDialog setProgress(int progress) 
    prgBar.setProgress(progress);
    return this;


public int getProgressMax() 
    return prgBar.getMax();


public int getProgress() 
    return prgBar.getProgress();


@Override
public void onClick(View v) 
    this.dismiss();

【讨论】:

天啊!那太简单了……你没有找到更简单的方法吗? @autowaaagh 您能否详细说明“使用无法覆盖的自己的布局”。据我了解,这意味着无法设置警报对话框按钮(按钮行)的样式。我说的对吗?

以上是关于Android:AlertDialog Button 不接受样式的主要内容,如果未能解决你的问题,请参考以下文章

Android:如何设置AlertDialog的宽度和高度,以及AlertDialog风格的按钮?

Android常见控件— — —AlertDialog

Android AlertDialog

转Android对话框 AlertDialog -- 不错不错

Android学习——AlertDialog

Android 可滚动的 AlertDialog 以编程方式