在对话框中设置标题分隔线的样式

18

我想知道如何去除或更改Dialog中的titleDivider颜色。这是在蜂巢+设备上显示在对话框标题下方的蓝线。

烦人的titleDivider线

我猜这是SDK布局的相关部分,但由于没有样式属性,我不知道如何设置样式。如果我尝试使用findViewById,就没有android.R.id.titleDivider。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:fitsSystemWindows="true">
    <TextView android:id="@android:id/title" style="?android:attr/windowTitleStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="@android:dimen/alert_dialog_title_height"
        android:paddingLeft="16dip"
        android:paddingRight="16dip"
        android:gravity="center_vertical|left" />
    <View android:id="@+id/titleDivider"
            android:layout_width="match_parent"
            android:layout_height="2dip"
            android:background="@android:color/holo_blue_light" />
    <FrameLayout
        android:layout_width="match_parent" android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        android:foreground="?android:attr/windowContentOverlay">
        <FrameLayout android:id="@android:id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>
</LinearLayout>

我尝试重写dialogTitleDecorLayout,只是在我的theme.xml中引用了dialog_title_holo.xml,但没有成功。错误信息如下:

错误:找不到与给定名称匹配的资源:属性“dialogTitleDecorLayout”。


1
如果你想要摆脱默认样式的某些部分,你必须完全放弃它,因为它在不同设备和操作系统版本之间有所不同。 - Display Name
1
请在@Sharad Mhaske处发布您的屏幕截图。 - GrIsHu
@GrlsHu:我已经发布了截图。 - Sharad Mhaske
看一下我的编辑器答案,它会帮助你的。 - Kostya Khuta
你可以随时选择自定义布局。设计你的自定义布局并将其放入对话框中。 - SweetWisher ツ
你可以通过一个非常简单的技巧实际上改变AlertDialog标题的颜色。https://dev59.com/9mUp5IYBdhLWcg3wbnQS#21401181/ - MatrixDev
15个回答

23
要获取对话框(AlertDialog)的标题分隔符(titleDivider)以更改其颜色,请执行以下操作:
int divierId = dialog.getContext().getResources()
                .getIdentifier("android:id/titleDivider", null, null);
View divider = dialog.findViewById(divierId);
divider.setBackgroundColor(getResources().getColor(R.color.creamcolor));

非常好的答案,非常感谢。对于空指针问题,您需要检查frameworks/base/core/res/res/layout/alert_dialog.xml文件或者在HierarchyViewer中查看确切的资源名称。 - Maciej Boguta
分隔符为空。对于自定义消息,与dialog.findViewById(android.R.id.message)相同。为什么会这样? - stackunderflow
请务必检查亚马逊 Kindle 设备,因为默认情况下它不会显示蓝色线条。 - Sharad Mhaske
@test 我使用这段代码片段也遇到了空指针异常,但仅在CyanogenMod ROM上发生。该代码在MIUI ROM上运行完美。有没有一种全局的方法来完成相同的操作? - Ali_Waris
如果使用DialogFragment,则此示例中的dialoggetDialog(),而不是getView()。并且始终检查if (divider != null) - lomza

13

你需要实现

myDialog = builder.create();
myDialog.setOnShowListener(new OnShowListenerMultiple());

//----------------------------
//Function to change the color of title and divider of AlertDialog
public static class OnShowListenerMultiple implements DialogInterface.OnShowListener {
    @Override
    public void onShow( DialogInterface dialog ) {
        if( !(dialog instanceof Dialog) )
            return;

        Dialog d = ((Dialog) dialog);
        final Resources resources = d.getContext().getResources();
        final int color = AppUtility.getColor( resources, R.color.defaultColor );

        try {
            int titleId = resources.getIdentifier( "android:id/alertTitle", null, null );
            TextView titleView = d.findViewById( titleId );
            titleView.setTextColor( color );
        }
        catch( Exception e ) {
            Log.e( "XXXXXX", "alertTitle could not change color" );
        }

        try {
            int divierId = resources.getIdentifier( "android:id/titleDivider", null, null );
            View divider = d.findViewById( divierId );
            divider.setBackgroundColor( color );
        }
        catch( Exception e ) {
            Log.e( "XXXXXX", "titleDivider could not change color" );
        }
    }
}

你能告诉我按钮分隔符的标识符吗? - khunshan

9

我通过使用DialogFragment.STYLE_NO_TITLE主题并在对话框布局中伪造标题栏来解决了这个问题。


1
好主意。我曾经也遇到了完全相同的问题,直到我找到了你的答案。我担心我不得不复制警报对话框布局并根据我的需求进行调整,但是你的解决方案要好得多。有时候安卓会让这样简单的任务变得如此困难,这有点傻。 - Paul
@Andraz:我知道你之前做过这项工作,但希望你能分享更多具体细节。例如,你是如何设置主题的?它是否对整个应用程序产生影响,还是只限于对话框?另外,你是如何“伪造”标题栏的? - PeteH
setStyle(SherlockDialogFragment.STYLE_NO_TITLE, R.style.Your_Style) - 我曾经使用SherlockActionBar。然后我用图片来伪装它(实际上我想让分隔栏的颜色与标题栏相同-橙色)。不太记得所有细节了,很久以前的事情了。 - Andraz

3

以下是我如何解决这个问题的(感谢http://joerg-richter.fuyosoft.com/?p=181):

MyDialogBuilder.class

public class MyDialogBuilder extends android.app.AlertDialog.Builder {

public MyDialogBuilder(Context context) {
    super(context);
}

@NonNull
@Override
public android.app.AlertDialog create() {
    final android.app.AlertDialog alertDialog = super.create();

    alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialog) {
            int titleDividerId = getContext().getResources()
                    .getIdentifier("titleDivider", "id", "android");

            View titleDivider = alertDialog.findViewById(titleDividerId);
            if (titleDivider != null) {
                titleDivider.setBackgroundColor(getContext().getResources()
                        .getColor(R.color.alert_dialog_divider));
            }
        }
    });

    return alertDialog;
}
}

2
在编写dialog.show()之前,请先编写:
int divierId = dialog.getContext().getResources().getIdentifier("android:id/titleDivider",   null, null);
View divider = dialog.findViewById(divierId);
if(divider!=null){
divider.setBackgroundColor(getResources().getColor(R.color.transparent));}

colors.xml中:
<color name="transparent">#00000000</color>

这对我有效,但你应该在divider上放置一个空指针检查。这在5.0及以上版本不起作用。 - Aaron Dancygier

2

使用

 <View android:id="@+id/titleDivider"
        android:layout_width="match_parent"
        android:layout_height="2dip"
        android:background=#CC3232 />

1
我发布的 XML 是 Android 源代码的一部分,所以我无法真正更改它。 - Andraz

1
如果你不想使用默认样式,不要使用AlertDialog。你可以选择带有对话框主题的Activity(使用自定义布局)。
<activity android:theme="@android:style/Theme.Dialog">

0

在colors.xml文件中:

<color name="transparent">#00000000</color>

在对话框中:
int divierId = dialog.getContext().getResources().getIdentifier("android:id/titleDivider",null, null);
View divider = d.findViewById(divierId); divider.setBackgroundColor(getResources().getColor(R.color.transparent));

0

你的想法是正确的。然而,你正在寻找的dialogTitleDecorLayout是一个私有资源,因此你无法以正常方式访问它。但是你仍然可以使用*语法来访问它:

<item name="*android:dialogTitleDecorLayout">@layout/dialog_title</item>

将这个添加到我的样式中,然后将 dialog_title.xml 复制到我的应用程序中并稍微修改一下,这在我的情况下解决了问题。

0
为了完全隐藏默认的蓝线(假设您在DialogFragment中):
    Dialog dialog = getDialog();
    if (dialog != null) {
        final int dividerId = dialog.getContext().getResources()
                .getIdentifier("android:id/titleDivider", null, null);
        View divider = dialog.findViewById(dividerId);
        if  (divider != null) {
            divider.setBackground(null);
        }
    }

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