【问题标题】:How can I change the color of AlertDialog title and the color of the line under it如何更改 AlertDialog 标题的颜色及其下方线条的颜色
【发布时间】:2013-01-04 13:27:32
【问题描述】:

我使用此命令更改了 AlertDialog 标题的颜色

alert.setTitle( Html.fromHtml("<font color='#FF7F27'>Set IP Address</font>"));

但我想更改标题下出现的线条的颜色;我怎样才能做到这一点 ?

注意:我不想使用自定义布局

【问题讨论】:

  • 您是否有特定的原因要避免自定义布局?您还有哪些需要满足的额外规定?
  • 您实际上可以通过一个非常简单的 hack 来更改 AlertDialog 标题的颜色。 stackoverflow.com/a/21401181/855884

标签: android android-alertdialog


【解决方案1】:

不幸的是,这不是一项特别简单的任务。 In my answer here,我详细介绍了如何调整ListSeparator的颜色,只需查看Android使用的父样式,创建新图像,并在原始样式的基础上创建新样式。不幸的是,与ListSeparator 的样式不同,AlertDialog 主题是内部的,因此不能作为父样式引用。没有简单的方法可以改变那条小蓝线!因此,您需要求助于制作自定义对话框。

如果这不是你的一杯茶...不要放弃!我很不安,因为没有简单的方法可以做到这一点,所以我建立了一个小项目github 用于制作快速定制的全息样式对话框(假设手机支持全息样式)。 您可以在此处找到该项目:https://github.com/danoz73/QustomDialog

它应该可以轻松地从无聊的蓝色变为令人兴奋的橙色!

该项目基本上是使用自定义对话框构建器的示例,在示例中,我创建了一个自定义视图,该视图似乎迎合了您在原始问题中给出的 IP 地址示例。

使用QustomDialog,要创建一个基本对话框(标题、消息),并为标题或分隔线使用所需的不同颜色,请使用以下代码:

private String HALLOWEEN_ORANGE = "#FF7F27";

QustomDialogBuilder qustomDialogBuilder = new QustomDialogBuilder(v.getContext()).
    setTitle("Set IP Address").
    setTitleColor(HALLOWEEN_ORANGE).
    setDividerColor(HALLOWEEN_ORANGE).
    setMessage("You are now entering the 10th dimension.");

qustomDialogBuilder.show();

为了添加自定义布局(例如,添加小 IP 地址EditText),您添加

setCustomView(R.layout.example_ip_address_layout, v.getContext())

到具有您设计的布局的构建器(IP 示例可以在 github 中找到)。我希望这有帮助。 Many thanks to Joseph Earl and his answer here.

【讨论】:

  • 为什么android仍然不支持改变alert对话框的颜色,我应该使用另一个对话框,还是问题出在哪里?
  • Android 可能正在尝试强制执行一致的 UI 模式,因此这可能是这具有挑战性的原因。这是我可以创建来帮助您的最佳解决方案。我希望你觉得它有用,或者至少有趣且内容丰富:)
  • 你好丹尼尔。感谢您分享您的工作。这很有帮助。我在实现这一点时面临一个问题。实际上,我想在此自定义对话框中使用 setItems 添加单项选择。当我添加列表时,它实际上将标题移动到列表下方。如何解决这个问题。
  • 好吧,也许还没有……我正面临列表下方标题的问题……抱歉。
  • @DanielSmith 嗨!干得好,但是您是否找到了上述“列表下方标题”的解决方案
【解决方案2】:

分隔线颜色:

这有点 hack,但它对我来说非常有用,而且它不需要任何外部库(至少在 Android 4.4 上)。

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.dialog)
       .setIcon(R.drawable.ic)
       .setMessage(R.string.dialog_msg);
//The tricky part
Dialog d = builder.show();
int dividerId = d.getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
View divider = d.findViewById(dividerId);
divider.setBackgroundColor(getResources().getColor(R.color.my_color));

您可以在alert_dialog.xml 文件中找到更多对话框的 ID。例如。 android:id/alertTitle 用于更改标题颜色...

更新:标题颜色

改变标题颜色的技巧:

int textViewId = d.getContext().getResources().getIdentifier("android:id/alertTitle", null, null);
TextView tv = (TextView) d.findViewById(textViewId);
tv.setTextColor(getResources().getColor(R.color.my_color));

【讨论】:

  • 即使在 KitKat 上,我也会在这里遇到android.util.AndroidRuntimeException: requestFeature() must be called before adding content
  • 我在我的应用程序的很多地方都使用了这段代码,而且它在任何地方都能正常工作。我只知道 DialogFragment 的问题,其中标题颜色没有 id android:id/alertTitle 但我没有找到正确的。
  • @platzhirsch,在我的自定义 DialogFragment 类中,我通过在 onStart() 中运行自定义代码来避免 requestFeature() 问题。您可以使用 getDialog() 访问那里的对话框。
  • 提醒未来可能遇到此问题的用户;出于某种原因,当我只使用一个通用对话框时,我必须使用“title”作为我的标识符名称,而不是“alertTitle”。不确定这是否在其他任何地方提到过,但只是想我会添加我的一点以希望有所帮助:P
  • 我在setTextColor()收到NullPointerException
【解决方案3】:

检查这对你有用...

public void setCustomTitle (View customTitleView)

您可以从以下链接获取详细信息。

http://developer.android.com/reference/android/app/AlertDialog.Builder.html#setCustomTitle%28android.view.View%29

CustomDialog.java

Dialog alert = new Dialog(this);
    alert.requestWindowFeature(Window.FEATURE_NO_TITLE);
    alert.setContentView(R.layout.title);
    TextView msg = (TextView)alert.findViewById(R.id.textView1);
    msg.setText("Hello Friends.\nIP address : 111.111.1.111");
    alert.show();

title.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Set IP address"
    android:textColor="#ff0000"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<ImageView 
    android:layout_width="fill_parent"
    android:layout_height="2dp"
    android:layout_marginTop="5dp"
    android:background="#00ff00"
    />
<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#775500"
    android:textAppearance="?android:attr/textAppearanceLarge" />

【讨论】:

  • 我试试这个,但我的 TextView 下仍然有蓝线
  • 我有一些代码。在“编辑”之后给出答案。你试试这个。
【解决方案4】:

这将为标题、图标和分隔线设置颜色。一定会随着任何新的 Android 版本而改变。

public static void colorAlertDialogTitle(AlertDialog dialog, int color) {
    int dividerId = dialog.getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
    if (dividerId != 0) {
        View divider = dialog.findViewById(dividerId);
        divider.setBackgroundColor(color);
    }

    int textViewId = dialog.getContext().getResources().getIdentifier("android:id/alertTitle", null, null);
    if (textViewId != 0) {
        TextView tv = (TextView) dialog.findViewById(textViewId);
        tv.setTextColor(color);
    }

    int iconId = dialog.getContext().getResources().getIdentifier("android:id/icon", null, null);
    if (iconId != 0) {
        ImageView icon = (ImageView) dialog.findViewById(iconId);
        icon.setColorFilter(color);
    }
}

记得在调用这个方法之前调用 dialog.show()。

【讨论】:

  • @Vlado 你在使用 appcompat 吗?如果是这样,这可能行不通。
【解决方案5】:

通过Dialog source code,我发现Title是在MidWindow类中通过膨胀dialog_title_holo.xml布局生成的。所以mTitleView的Id是title,divider的Id是titleDivider

我们可以通过android.R.id.title访问title的ID。

并通过Resources.getSystem().getIdentifier("titleDivider","id", "android"); 访问titleDivider 的ID

我用来改变标题方向和改变颜色的最终代码是:

TextView mTitle = (TextView)findViewById(android.R.id.title);
mTitle.setGravity(Gravity.RIGHT|Gravity.CENTER_VERTICAL);
int x = Resources.getSystem().getIdentifier("titleDivider","id", "android");
View titleDivider = findViewById(x);
titleDivider.setBackgroundColor(getContext().getResources().getColor(R.color.some_color));

【讨论】:

  • 这是一个完整的答案!使用 android.R.id.title 也可以更改标题!
  • 很好的答案,对我帮助很大!我不得不改变: TextView mTitle = (TextView)findViewById(android.R.id.title);到:TextView mTitle = (TextView)dialog.findViewById(android.R.id.title);让这个工作。
  • 这个对我有用,我正在使用一个继承@android:style/Theme.Dialog的Activity。可以自定义分隔线和标题颜色。 +1
【解决方案6】:

如果你不想要一个“库”,你可以使用这个糟糕的 hack:

((ViewGroup)((ViewGroup)getDialog().getWindow().getDecorView()).getChildAt(0)) //ie LinearLayout containing all the dialog (title, titleDivider, content)
.getChildAt(1) // ie the view titleDivider
.setBackgroundColor(getResources().getColor(R.color.yourBeautifulColor));

这是在 4.x 上测试和工作的;没有经过测试,但如果我的记忆力很好,它应该适用于 2.x 和 3.x

【讨论】:

  • 这对 4.x 非常有用,我也没有尝试过其他的,所以我会试一试并确认它
  • getDialog() 给我一个错误“方法 getDialog() 未定义为 MainActivity 类型”它要求我创建一个方法
【解决方案7】:

在 onCreateView 类中,我放了这个:

Dialog d = getDialog();
    d.setTitle(Html.fromHtml("<font color='#EC407A'>About</font>"));
    int dividerId = d.getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
    View divider = d.findViewById(dividerId);
    divider.setBackgroundColor(getResources().getColor(R.color.colorPrimary));

colorPrimary 链接到存储所有颜色的 colors.xml 文件。此外,d.setTitle 提供了一种设置标题颜色的 hacky 方式。

【讨论】:

    【解决方案8】:

    这是另一种解决方案(基于建议的答案),它在一个类中处理对话框的样式,而无需担心更改样式时对话框的状态 - 对话框可能已经显示或刚刚初始化。

    使用示例:

    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    AlertDialog dialog = builder.create(); //or builder.show()
    DialogViewDecorator.decorate(dialog, android.R.color.holo_red_light); //can also set the defaut color in the class
    

    实施:

    public class DialogViewDecorator {
    
    private static final
    @ColorRes int DEFAULT_TITLE_DIVIDER_COLOR = android.R.color.holo_orange_light;
    
    public static void decorate(Dialog dialog) {
        decorate(dialog, DEFAULT_TITLE_DIVIDER_COLOR);
    }
    
    /**
     * Sets the title divider color when the view is shown by setting DialogInterface.OnShowListener on the dialog.
     * <p/>
     * If you want to do other things onShow be sure to extend OnDecoratedDialogShownListener(call super.show(...)!)
     * and call {@link #decorate(Dialog, int, OnDecoratedDialogShownListener)}.
     *
     * @param dialog
     * @param titleDividerColor
     */
    public static void decorate(Dialog dialog, final int titleDividerColor) {
        decorate(dialog, titleDividerColor, new OnDecoratedDialogShownListener(titleDividerColor));
    }
    
    /**
     * Method for setting a extended implementation of OnDecoratedDialogShownListener. Don't forget to call super
     * or the titleDividerColor wont be applied!
     *
     * @param dialog
     * @param titleDividerColor
     * @param OnShowListener
     * @param <T>
     */
    public static <T extends OnDecoratedDialogShownListener> void decorate(Dialog dialog, int titleDividerColor, T OnShowListener) {
        if (dialog == null || titleDividerColor <= 0) { return; }
    
        if (dialog.isShowing()) {
            setTitleDividerColor(dialog, titleDividerColor);
        } else {
            dialog.setOnShowListener(OnShowListener);
        }
    }
    
    private static void setTitleDividerColor(DialogInterface dialogInterface, int titleDividerColor) {
        try {
            Dialog dialog = (Dialog) dialogInterface;
            int dividerId = dialog.getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
            View divider = dialog.findViewById(dividerId);
            if (divider != null) {
                divider.setBackgroundColor(dialog.getContext().getResources().getColor(titleDividerColor));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
    public static class OnDecoratedDialogShownListener implements DialogInterface.OnShowListener {
        private int titleDividerColor;
    
        public OnDecoratedDialogShownListener() {
            this.titleDividerColor = DEFAULT_TITLE_DIVIDER_COLOR;
        }
    
        public OnDecoratedDialogShownListener(int titleDividerColor) {
            this.titleDividerColor = titleDividerColor;
        }
    
        @Override
        public void onShow(DialogInterface dialogInterface) {
            setTitleDividerColor(dialogInterface, titleDividerColor);
        }
    }}
    

    【讨论】:

      【解决方案9】:

      如果您正在为警报对话框创建自定义布局

      那么你可以像这样轻松添加来改变颜色

      <LinearLayout
          android:id="@+id/DialogTitleBorder"
          android:layout_width="fill_parent"
          android:layout_height="1dip"
          android:layout_below="@id/mExitDialogDesc"
          android:background="#4BBAE3"            <!--change color easily -->
          >
      
      </LinearLayout>
      

      【讨论】:

        【解决方案10】:
            ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.BLACK);
        
            String title = context.getString(R.string.agreement_popup_message);
            SpannableStringBuilder ssBuilder = new SpannableStringBuilder(title);
            ssBuilder.setSpan(
                    foregroundColorSpan,
                    0,
                    title.length(),
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            );
        
        AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(context);
        alertDialogBuilderUserInput.setTitle(ssBuilder)
        

        【讨论】:

          【解决方案11】:

          如果您使用自定义标题布局,那么您可以像alertDialog.setCustomTitle(customTitle); 一样使用它

          示例

          在 UI 线程使用对话框,如:

           LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
           View customTitle = inflater.inflate(R.layout.customtitlebar, null);
           AlertDialog.Builder d = new AlertDialog.Builder(this);
           d.setCustomTitle(customTitle);
           d.setMessage("Message");
           d.setNeutralButton("OK", null);
           d.show();
          

          自定义标题栏.xml

          <?xml version="1.0" encoding="utf-8"?>
          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical"
              android:background="#525f67">
          
              <ImageView
                  android:id="@+id/icon"
                  android:layout_width="40dp"
                  android:layout_height="40dp"
                  android:src="@drawable/ic_launcher"
                  android:layout_alignParentTop="true"
                  android:layout_alignParentLeft="true" >
              </ImageView>
          
              <TextView
                  android:id="@+id/customtitlebar"
                  android:layout_width="match_parent"
                  android:layout_height="40dp"
                  android:textColor="#ffffff"
                  android:text="Title Name"
                  android:padding="3px"
                  android:textStyle="bold" 
                  android:layout_toRightOf="@id/icon"
                  android:layout_alignParentTop="true"
                  android:gravity="center_vertical"/>
          
               <ImageView
                  android:layout_width="match_parent"
                  android:layout_height="2dp"
                  android:background="#ff0000" 
                  android:layout_below="@id/icon"><!-- This is line below the title -->
              </ImageView>
          
          </RelativeLayout>
          

          【讨论】:

          • 我想改变红色椭圆内线的颜色
          【解决方案12】:

          从这个答案继续:https://stackoverflow.com/a/15285514/1865860,我从@daniel-smith 复制了不错的 github 存储库并进行了一些改进:

          • 改进的示例活动
          • 改进的布局
          • 固定setItems方法
          • items_list 中添加了分隔符
          • 点击关闭对话框
          • 支持setItems 方法中的禁用项目
          • listItem触摸反馈
          • 可滚动的对话框消息

          链接:https://github.com/dentex/QustomDialog

          【讨论】:

            【解决方案13】:

            不要在对话框中使用分隔线,而是在自定义布局中使用视图并将布局设置为对话框中的自定义布局。

            custom_popup.xml:

            <?xml version="1.0" encoding="utf-8"?>
            <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            
                <com.divago.view.TextViewMedium
                    android:id="@+id/txtTitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:paddingBottom="10dp"
                    android:paddingTop="10dp"
                    android:text="AlertDialog"
                    android:textColor="@android:color/black"
                    android:textSize="20sp" />
            
                <View
                    android:id="@+id/border"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:layout_below="@id/txtTitle"
                    android:background="@color/txt_dark_grey" />
            
                <ScrollView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_below="@id/border"
                    android:scrollbars="vertical">
            
                    <com.divago.view.TextViewRegular
                        android:id="@+id/txtPopup"
                        android:layout_margin="15dp"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />
                </ScrollView>
            </RelativeLayout>
            

            activity.java:

            public void showPopUp(String title, String text) {
            
                LayoutInflater inflater = getLayoutInflater();
                View alertLayout = inflater.inflate(R.layout.custom_popup, null);
            
                TextView txtContent = alertLayout.findViewById(R.id.txtPopup);
                txtContent.setText(text);
            
                TextView txtTitle = alertLayout.findViewById(R.id.txtTitle);
                txtTitle.setText(title);
            
                AlertDialog.Builder alert = new AlertDialog.Builder(this);
                alert.setView(alertLayout);
                alert.setCancelable(true);
            
                alert.setPositiveButton("Done", new DialogInterface.OnClickListener() {
            
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
            
                AlertDialog dialog = alert.create();
                dialog.show();
            }
            

            【讨论】:

              【解决方案14】:

              如果您使用扩展对话框,请使用:

              requestWindowFeature(Window.FEATURE_NO_TITLE);
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2023-03-06
                • 1970-01-01
                • 1970-01-01
                • 2016-02-20
                相关资源
                最近更新 更多