Android-стиль AlertDialog
у меня есть диалоговое окно оповещения в приложении, как показано ниже.
Я хочу, чтобы заголовок и строка, которая отделяет тело заголовка сообщения, были оранжевого цвета. как я могу это сделать? То, что я пробовал, использует пользовательский стиль, как показано ниже. Но это не сработало.
<style name="AboutDialog" parent="@android:style/Theme.Dialog">
<item name="android:textColor">#E5492A</item>
</style>
мой код диалога оповещения:
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();
}
4 ответов
вместо:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
new ContextThemeWrapper(MainActivity.context, R.style.AboutDialog));
попробуйте это:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this, R.style.AboutDialog);
Примечание: это доступно только для API 11 (Android 3.0) и выше.
Если вам нужно поддерживать Android AlertDialog
EDIT добавлен действительно неряшливый Хак на основе отражения
если вы действительно застряли и не хотите реализовывать пользовательский диалог, попробуйте следующий.
после того, как вы построили диалог и как раз перед тем, как вы хотите вернуть его, вместо этого:
return alertDialog.create();
этого:
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;
теперь добавьте этот очень неприятный метод на основе отражения:
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
}
}
я проверил это на Android 2.2 и Android 4.0 и она работает. Он может не делать именно то, что вы хотите, поэтому вам нужно попробовать. Я не могу гарантировать, что он будет работать на всех устройствах или на будущих версиях Android, так как это зависит от пути the AlertDialog
класс реализован (если они изменят это в будущем, это, вероятно, больше не будет работать).
просто несколько заметок для тех, кто заботится:
причина, по которой я использую
setOnShowListener()
это потому что вы не можете добраться до внутреннейView
объектыAlertDialog
пользы до тех пор пока после того как они не будут надуты. Они не раздуваются сразу, когда вы создаетеAlertDialog
, это происходит спустя некоторое время. Используя слушателя мы можем получить контроль после макет завышен, но перед это.я использую отражение для доступа к внутренним переменным-членам в
AlertDialog
реализация. Как только я получу доступ кTextView
который содержит заголовок, я должен обезьяна вокруг, чтобы найти горизонтальную линию, которая используется для отделения заголовка от сообщения. Для этого я получаюLayout
что окружает название (этоLayout
содержит значок предупреждения и текст заголовка). Тогда я получаюLayout
что окружает то (этоLayout
обертывает значок, текст заголовка и разделитель). Затем я смотрю на всех детей окружающего макета и устанавливаю цвет на всехImageView
объекты. Разделитель реализован какImageView
используя drawable, поэтому невозможно просто изменить цвет. Примечание: альтернатива использованиюsetColorFilter()
было бы заменить drawable в ImageView подходящим цветным drawable здесь.
Спасибо за вызов, это было забавно понять это: - D
кстати, его поздний ответ, возможно, это будет полезно для кого-то. чтобы создать пользовательский AlertDialog и иметь те же аккуратные кнопки, как по умолчанию AlertDialog. следуйте простой метод ниже
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();
}
});
попробуйте создать custom layout
для диалога и укажите, что layout
в диалог оповещения с помощью
dialog.setContentView(R.layout.customDialogLayout);
вы можете посмотреть это пример для пользовательского диалогового окна.
вы можете использовать этот проект AlertDialogPro. Включите этот проект в свой и определите свою тему, как показано ниже:
<style name="YourAppTheme.AlertDialogProTheme" parent="AlertDialogProTheme.Holo.Light">
<!-- Custom the title -->
<item name="android:windowTitleStyle">@style/YourDialogWindowTitle</item>
<!-- Change the title line to orange -->
<item name="adpTitleDividerBackground">#E5492A</item>
</style>
<style name="YourDialogWindowTitle" parent="DialogWindowTitle.Holo.Light">
<item name="android:textColor">#E5492A</item>
</style>
и укажите эту тему в тему вашего приложения с атрибутом "alertDialogProTheme":
<style name="AppTheme" parent="AppBaseTheme">
...
<item name="alertDialogProTheme">@style/YourAppTheme.AlertDialogProTheme</item>
</style>
Используйте AlertDialogPro.Строитель для построения диалога:
AlertDialogPro.Builder builder = new AlertDialogPro.Builder(getContext());
builder.setTitle(R.string.app_name).
setMessage("Message").
setPositiveButton("Rate Now", null).
setNeutralButton("Remind me later", null).
setNegativeButton("No,thanks", null).
show();