Styling titleDivider in Dialog
Asked Answered
M

15

18

I am wondering how it is possible to get rid of (or change color) titleDivider in Dialog. It is a blue line below dialog title shown on honeycomb+ devices.

Annoying titleDivider line

I guess this is relevant piece of layout from SDK, but since there is no style attribute I dont know how to style it. If i try with findViewById there is no 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>

I have tried to override dialogTitleDecorLayout which is only reference to dialog_title_holo.xml in my theme.xml, but without success. Error is:

error: Error: No resource found that matches the given name: attr 'dialogTitleDecorLayout'.

Minni answered 11/6, 2012 at 10:49 Comment(6)
if you want to get rid of some part of default style, you must drop it completely, because it differs between devices and OS versionsKnit
Post your screenshot @Sharad MhaskeCalibre
@GrlsHu:i have posted the screenshotRatchford
watch my editer answer, it will help youChalcocite
You can always go with custom layout.. Design your custom layout and put it inn dailogApodal
You can actually change color of AlertDialog title by a very simple hack. https://mcmap.net/q/189636/-how-to-change-alert-dialog-header-divider-color-androidDemit
M
9

I solved the issue by using DialogFragment.STYLE_NO_TITLE theme and then faking title bar in dialog layout.

Minni answered 11/6, 2012 at 11:29 Comment(3)
Great idea. I was struggling with the EXACT same problem until i found your answe. I was afraid i would have to copy the alert dialog layout and adjust it to my needs but your solution is much, much better. It's kind of silly how Android sometimes makes such simple tasks so hard...Pica
@Andraz: I know you did this work a while ago but was hoping you could share more of the specifics. For example, how did you set the theme? Does that have app-wide effect or can you limit it to just the the dialogs? Also, how did you "fake" the title bar?Tindle
setStyle(SherlockDialogFragment.STYLE_NO_TITLE, R.style.Your_Style) - I was using SherlockActionBar. Then I faked it with image (actually I wanted divider bar to be same color as title bar - orange). Dont really remember all details, quite long time ago.Minni
R
23

To get a reference to titleDivider of AlertDialog to change its color:

int divierId = dialog.getContext().getResources()
                .getIdentifier("android:id/titleDivider", null, null);
View divider = dialog.findViewById(divierId);
divider.setBackgroundColor(getResources().getColor(R.color.creamcolor));
Ratchford answered 31/12, 2013 at 9:26 Comment(5)
great answer, thanks alot for it. for the null pointer stuff, you need to check frameworks/base/core/res/res/layout/alert_dialog.xml file or just in HierarchyViewer, what are the exact resource namesCalondra
divider is null. same to dialog.findViewById(android.R.id.message) for custom message. why is that?Tillion
Please be sure to have check for amazon kindle devices as it doesnt show blue line by default.Ratchford
@test I also got a null pointer exception using this code snippet, but only on CyanogenMod roms. This code works perfectly on MIUI roms. Is there a global way to do the same??Paulina
In case of using DialogFragment, dialog in this example is a getDialog(), NOT getView(). And always check if (divider != null).Minny
F
13

You need to implement

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" );
        }
    }
}
Fine answered 12/4, 2014 at 0:44 Comment(1)
can you tell identifier for button dividers?Topple
M
9

I solved the issue by using DialogFragment.STYLE_NO_TITLE theme and then faking title bar in dialog layout.

Minni answered 11/6, 2012 at 11:29 Comment(3)
Great idea. I was struggling with the EXACT same problem until i found your answe. I was afraid i would have to copy the alert dialog layout and adjust it to my needs but your solution is much, much better. It's kind of silly how Android sometimes makes such simple tasks so hard...Pica
@Andraz: I know you did this work a while ago but was hoping you could share more of the specifics. For example, how did you set the theme? Does that have app-wide effect or can you limit it to just the the dialogs? Also, how did you "fake" the title bar?Tindle
setStyle(SherlockDialogFragment.STYLE_NO_TITLE, R.style.Your_Style) - I was using SherlockActionBar. Then I faked it with image (actually I wanted divider bar to be same color as title bar - orange). Dont really remember all details, quite long time ago.Minni
B
3

Here is how I resolved that (thanks to 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;
}
}
Bomke answered 20/1, 2015 at 18:51 Comment(0)
H
2

use

 <View android:id="@+id/titleDivider"
        android:layout_width="match_parent"
        android:layout_height="2dip"
        android:background=#CC3232 />
Headdress answered 11/6, 2012 at 10:55 Comment(1)
The xml i posted is part of android source, so i cannot really change itMinni
R
2

Before write dialog.show(), write:

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));}

In colors.xml:

<color name="transparent">#00000000</color>
Reconstruct answered 25/1, 2016 at 5:57 Comment(1)
This works for me but you should put a null pointer check on divider. This will not work on 5.0 and up.Alongside
T
1

If you don't want to use Default style, don't use AlertDialog. You could go with Activity(with your custom layout) with Dialog Theme.

<activity android:theme="@android:style/Theme.Dialog">
Tonie answered 31/12, 2013 at 8:8 Comment(0)
A
0

This one is tested on some 4.x devices:

    TextView title = (TextView)getWindow().getDecorView().findViewById(android.R.id.title);
    ((ViewGroup)title.getParent()).getChildAt(1).setVisibility(View.GONE);
Aec answered 4/7, 2013 at 14:48 Comment(1)
this yielded a NPE. Was the purpose to eliminate the title separator as per the original question? Or something else?Tindle
P
0

Your idea was correct. However, dialogTitleDecorLayout you were looking for is a private resource, so you can't access it in a normal way. But you still can access it using * syntax:

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

Adding this to my own style and simply copying dialog_title.xml to my app and changing it slightly solved the problem in my case.

Prisilla answered 17/12, 2013 at 15:58 Comment(0)
C
0

Do you watchthis and there is a pcecial library for that, you can watch it there. And the last link will solve you problem

Chalcocite answered 31/12, 2013 at 8:9 Comment(0)
T
0

These is no way hiding it by control brotha.. I've had the same problem. only thing you can do is create your own CustomDialog

Here is a sample App

Download and have look at the design pattern, then it will be easy

Here is one Tutorial About making Custom Dialog

Important part is after creating the DialogObject don't set the Title by setTitle() create TextView inside your CustomLayout and call it from findViewByID() and set your title

Tibbs answered 31/12, 2013 at 8:12 Comment(0)
L
0

you can make a custom dialog like this:

    Dialog dialog = new Dialog(this);
    dialog.setContentView(R.layout.custom_dialog);
    Button okay = (Button) dialog.findViewById(R.id.button1);
    okay.setOnClickListener(new OnClickListener() {

         public void onClick(View arg0) {

           // do your work
         }
    });

Set a custom title in layout don't use android

     dialog.setTitle();

and your custom_dialog.xml

  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:android1="http://schemas.android.com/apk/res/android"
   android:id="@+id/layout_root"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical"
   android:padding="10dp">

  <TextView
      android:id="@+id/textView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textColor="#ffffff"
      android:textSize="40sp" 
      android:text="Hello"/>


    <Button
        android:id="@+id/button1"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="150dp"
        android:text="OK" />

    </RelativeLayout>
Lissome answered 31/12, 2013 at 8:14 Comment(0)
C
0

"Removing the blue line" if I guess correctly means dropping the border between the title of the dialog and it's body. That border come from the Holo theme, so it's not possible to drop it without using your custom layout.

Create a file named custom-dialog.xml with the following content (it's just an example..modify it as you want):

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

    <ImageView
        android:id="@+id/dialogTopImage"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="0.12"
        android:padding="10dp" />

    <LinearLayout
        android:id="@+id/dialogLine"
        android:layout_width="fill_parent"
        android:layout_height="3dp"
        android:background="@drawable/green_btn"
        android:orientation="vertical" />

    <TextView
        android:id="@+id/dialogText"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="0.32"
        android:padding="5dp"
        android:text=""
         />

    <LinearLayout
        android:id="@+id/general_dialog_layout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_gravity="center"
        android:layout_marginBottom="5dp"
        android:layout_weight="0.11"
        android:gravity="center"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/dialogButton"
            android:layout_width="100dp"
            android:textSize="8pt"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:background="@drawable/green_btn"
            android:gravity="center"
            android:text="Ok" />

</LinearLayout>

As you see I'm using resources and stuff that won't be in your project, but you can remove them safely. The result in my case is more or less the following one, with an image at top that I'll programatically set in the code.

simple screenshot

To create the dialog then use something like:

private Dialog createAndShowCustomDialog(String message, Boolean positive, Drawable d, View.OnClickListener cl, String text1) {

    final Dialog dialog = new Dialog(this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(R.layout.general_dialog_layout);
    // BIND
    ImageView image = (ImageView) dialog.findViewById(R.id.dialogTopImage);
    TextView text = (TextView) dialog.findViewById(R.id.dialogText);
    Button button = (Button) dialog.findViewById(R.id.dialogButton);
    LinearLayout line = (LinearLayout) dialog.findViewById(R.id.dialogLine);

    // SET WIDTH AND HEIGHT
    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int width = (int) (displaymetrics.widthPixels * 0.85);
    int height = (int) (displaymetrics.heightPixels * 0.60);
    WindowManager.LayoutParams params = getWindow().getAttributes();
    params.width = width;
    dialog.getWindow().setLayout(width, height);


    // SET TEXTS
    text.setText(message);
    button.setText(text1);

    // SET IMAGE
    if (d == null) {
        image.setImageDrawable(getResources().getDrawable(R.drawable.font_error_red));
    } else {
        image.setImageDrawable(d);
    }

    // SET ACTION
    if (cl == null) {
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
    } else {
        button.setOnClickListener(cl);
    }


    // SHOW
    dialog.show();
    return dialog;
}
Countrywide answered 31/12, 2013 at 8:16 Comment(0)
R
0

In colors.xml:

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

In dialog:

int divierId = dialog.getContext().getResources().getIdentifier("android:id/titleDivider",null, null);

View divider = d.findViewById(divierId); divider.setBackgroundColor(getResources().getColor(R.color.transparent));

Reconstruct answered 25/1, 2016 at 6:2 Comment(0)
M
0

In order to hide the default blue line completely (assuming you're in 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);
        }
    }
Minny answered 11/10, 2016 at 18:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.