I have an alert dialog in the app as shown below.
I want the title and the line which separates the title - message body to be in orange colour. how can i do this? What i tried is using custom style as shown below. But this did not work.
<style name="AboutDialog" parent="@android:style/Theme.Dialog">
<item name="android:textColor">#E5492A</item>
</style>
my alert dialog code:
AlertDialog.Builder alertDialog = new AlertDialog.Builder( new ContextThemeWrapper(MainActivity.context, R.style.AboutDialog));
alertDialog.setTitle("Sample");
alertDialog.setMessage(R.string.rate_dialog_text);
alertDialog.setPositiveButton(R.string.rate_now_text,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MainActivity.context.startActivity(new Intent(
Intent.ACTION_VIEW, Uri
.parse("market://details?id="
+ MainActivity.APP_PNAME)));
if (editor != null) {
editor.putBoolean("dontshowagain", true);
editor.commit();
}
dialog.dismiss();
}
});
alertDialog.setNeutralButton(R.string.remind_later_text,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.setNegativeButton(R.string.no_thanks_text,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (editor != null) {
editor.putBoolean("dontshowagain", true);
editor.commit();
}
dialog.dismiss();
}
});
return alertDialog.create();
}
Instead of:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
new ContextThemeWrapper(MainActivity.context, R.style.AboutDialog));
Try this:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this, R.style.AboutDialog);
NOTE: This is only available for API 11 (Android 3.0) and above.
If you need to to support Android < 3.0 you probably have to create a custom dialog (instead of using AlertDialog
EDIT Added really sleazy reflection-based hack
If you are really stuck and don't want to implement a custom dialog, then try the following.
After you've built the dialog and just before you want to return it, instead of this:
return alertDialog.create();
do this:
AlertDialog ad = alertDialog.create(); // Create the dialog
// Add listener so we can modify the dialog before it is shown
ad.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
// Set the text color on the dialog title and separator
setTextColor(dialogInterface, 0xFFE5492A);
}
});
return ad;
Now add this very nasty reflection-based method:
public void setTextColor(DialogInterface alert, int color) {
try {
Class c = alert.getClass();
Field mAlert = c.getDeclaredField("mAlert");
mAlert.setAccessible(true);
Object alertController = mAlert.get(alert);
c = alertController.getClass();
Field mTitleView = c.getDeclaredField("mTitleView");
mTitleView.setAccessible(true);
Object dialogTitle = mTitleView.get(alertController);
TextView dialogTitleView = (TextView)dialogTitle;
// Set text color on the title
dialogTitleView.setTextColor(color);
// To find the horizontal divider, first
// get container around the Title
ViewGroup parent = (ViewGroup)dialogTitleView.getParent();
// Then get the container around that container
parent = (ViewGroup)parent.getParent();
for (int i = 0; i < parent.getChildCount(); i++) {
View v = parent.getChildAt(i);
if (v instanceof ImageView) {
// We got an ImageView, that should be the separator
ImageView im = (ImageView)v;
// Set a color filter on the image
im.setColorFilter(color);
}
}
} catch (Exception e) {
// Ignore any exceptions, either it works or it doesn't
}
}
I tested this on Android 2.2 and Android 4.0 and it works. It may not do exactly what you want, so you'll need to try it. I can't guarantee it will work on all devices or on future versions of Android, since it depends a lot on the way the AlertDialog
class is implemented (if they change that in the future this probably won't work anymore).
Just a few notes for anyone who cares:
The reason that I use setOnShowListener()
is because you can't actually get to the internal View
objects that AlertDialog
uses until after they have been inflated. They don't get inflated immediately when you create an AlertDialog
, it happens some time later. Using the listener we can get control after the layout is inflated but before the Dialog
is shown.
I'm using reflection to access in internal member variables in the AlertDialog
implementation. Once I get access to the TextView
that contains the title, I have to monkey around to find the horizontal line that is used to separate the title from the message. To do this I get the Layout
that surrounds the title (this Layout
contains the alert icon and title text). Then I get the Layout
that surrounds that (this Layout
wraps the icon, title text and the separator). Then I look at all children of the surrounding layout and set the color on all ImageView
objects in there. The separator is implemented as an ImageView
using a drawable, therefore it isn't possible to just change the color. Note: An alternative to using setColorFilter()
would be to replace the drawable in the ImageView with a suitably colored drawable here.
Thanks for the challenge, it was kinda fun to figure this out :-D
by the way its a late answer, maybe it will be useful for someone. to create Custom AlertDialog and have the same neat buttons like the Default AlertDialog. follow the simple method below
final AlertDialog.Builder demoDialog = new AlertDialog.Builder(this);
final LayoutInflater inflator = this.getLayoutInflater();
final View view = inflator.inflate(R.layout.passcode_req_dialog_template, null);
demoDialog.setView(view)
.setPositiveButton(R.string.ok_button_text, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setNegativeButton(R.string.cancel_button_text, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
final AlertDialog dialog = passwordDialog.create();
dialog.show();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Get the work done here when pressing positive button
dialog.dismiss();
}
});
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Get the work done here when pressing negative button
dialog.dismiss();
}
});
Try to create a custom layout
for dialog and provide that layout
to your alert dialog by using
dialog.setContentView(R.layout.customDialogLayout);
You can see this example for custom dialog.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With