Как изменить тему для AlertDialog

Мне было интересно, может ли кто-нибудь помочь мне. Я пытаюсь создать пользовательский AlertDialog. Для этого я добавил следующую строку кода в styles.xml

  @drawable/color_panel_background   
  • color_panel_background.9.png находится в папке с возможностью переноса. Это также доступно в папке Android SDK res.

Основным видом деятельности является следующее.

 package com.customdialog; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; public class CustomDialog extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.setTheme(R.style.CustomAlertDialog); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("HELLO!"); builder .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { //MyActivity.this.finish(); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { //dialog.cancel(); } }); AlertDialog alertdialog = builder.create(); alertdialog.show(); } } 

Чтобы применить тему к AlertDialog, мне пришлось установить тему в текущий контекст.

Тем не менее, я просто не могу заставить приложение отображать настроенный AlertDialog. Может ли кто-нибудь помочь мне с этим?

    В Dialog.java (Android src) используется ContextThemeWrapper. Таким образом, вы могли бы скопировать идею и сделать что-то вроде:

    AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AlertDialogCustom));

    А затем нарисуйте его так, как хотите:

         

    У меня была проблема с этим вопросом, связанная с AlertDialog используя sdk 1.6, как описано здесь: http://markmail.org/message/mj5ut56irkrkc4nr

    Я решил проблему, выполнив следующие действия:

      new AlertDialog.Builder( new ContextThemeWrapper(context, android.R.style.Theme_Dialog)) 

    Надеюсь это поможет.

    Я написал статью в своем блоге о том, как настроить макет AlertDialog с файлами стиля XML. Основная проблема заключается в том, что вам нужны разные определения стиля для разных параметров макета. Вот шаблон, основанный на стиле AlertDialog для Holo Light Platform версии 19 для файла стиля, который должен охватывать кучу стандартных макетов, таких как размеры текста и цвета фона.

            

    Я боролся с этим – вы можете android:alertDialogStyle="@style/AlertDialog" фон диалога с помощью android:alertDialogStyle="@style/AlertDialog" в своей теме, но он игнорирует любые настройки текста, которые у вас есть. Как сказано выше, @rflexor не может быть сделано с SDK до Honeycomb (ну, вы можете использовать Reflection ).

    Мое решение, в двух словах, состояло в том, чтобы стилизовать фон диалога с использованием вышеизложенного, а затем установить пользовательский заголовок и представление контента (используя макеты, такие же, как в SDK).

    Моя обложка:

     import com.mypackage.R; import android.app.AlertDialog; import android.content.Context; import android.graphics.drawable.Drawable; import android.view.View; import android.widget.ImageView; import android.widget.TextView; public class CustomAlertDialogBuilder extends AlertDialog.Builder { private final Context mContext; private TextView mTitle; private ImageView mIcon; private TextView mMessage; public CustomAlertDialogBuilder(Context context) { super(context); mContext = context; View customTitle = View.inflate(mContext, R.layout.alert_dialog_title, null); mTitle = (TextView) customTitle.findViewById(R.id.alertTitle); mIcon = (ImageView) customTitle.findViewById(R.id.icon); setCustomTitle(customTitle); View customMessage = View.inflate(mContext, R.layout.alert_dialog_message, null); mMessage = (TextView) customMessage.findViewById(R.id.message); setView(customMessage); } @Override public CustomAlertDialogBuilder setTitle(int textResId) { mTitle.setText(textResId); return this; } @Override public CustomAlertDialogBuilder setTitle(CharSequence text) { mTitle.setText(text); return this; } @Override public CustomAlertDialogBuilder setMessage(int textResId) { mMessage.setText(textResId); return this; } @Override public CustomAlertDialogBuilder setMessage(CharSequence text) { mMessage.setText(text); return this; } @Override public CustomAlertDialogBuilder setIcon(int drawableResId) { mIcon.setImageResource(drawableResId); return this; } @Override public CustomAlertDialogBuilder setIcon(Drawable icon) { mIcon.setImageDrawable(icon); return this; } } 

    alert_dialog_title.xml (взято из SDK)

             

    alert_dialog_message.xml

         

    Затем просто используйте CustomAlertDialogBuilder вместо AlertDialog.Builder для создания ваших диалогов и просто вызовите setTitle и setMessage как обычно.

       new AlertDialog.Builder(new ContextThemeWrapper(context,R.style.AlertDialogCustom)) .setMessage(Html.fromHtml(Msg)) .setPositiveButton(posBtn, okListener) .setNegativeButton(negBtn, null) .create() .show(); 

    Вы можете напрямую назначить тему при запуске Builder:

     AlertDialog.Builder builder = new AlertDialog.Builder( getActivity(), R.style.MyAlertDialogTheme); 

    Затем настройте свою тему в своих values/styles.xml

       

    Думаю, это невозможно. По крайней мере, не с Строителем. Я работаю с 1.6, а реализация в Builder.create ():

     public AlertDialog create() { final AlertDialog dialog = new AlertDialog(P.mContext); P.apply(dialog.mAlert); [...] } 

    который вызывает конструктор «AlertDialog», созданный не темой, который выглядит так:

     protected AlertDialog(Context context) { this(context, com.android.internal.R.style.Theme_Dialog_Alert); } 

    В AlertDialog есть второй конструктор для изменения тем:

     protected AlertDialog(Context context, int theme) { super(context, theme); [...] } 

    что Строитель просто не звонит.

    Если Dialog довольно общий, я бы попытался написать подclass AlertDialog, вызвав второй конструктор и используя этот class вместо механизма Builder.

    Лучший способ сделать это – использовать настраиваемый диалог и настраивать в соответствии с вашими потребностями здесь – это пример диалогового windows …

    введите описание изображения здесь

     public class CustomDialogUI { Dialog dialog; Vibrator vib; RelativeLayout rl; @SuppressWarnings("static-access") public void dialog(final Context context, String title, String message, final Runnable task) { dialog = new Dialog(context); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.custom); dialog.setCancelable(false); TextView m = (TextView) dialog.findViewById(R.id.message); TextView t = (TextView) dialog.findViewById(R.id.title); final Button n = (Button) dialog.findViewById(R.id.button2); final Button p = (Button) dialog.findViewById(R.id.next_button); rl = (RelativeLayout) dialog.findViewById(R.id.rlmain); t.setText(bold(title)); m.setText(message); dialog.show(); n.setText(bold("Close")); p.setText(bold("Ok")); // color(context,rl); vib = (Vibrator) context.getSystemService(context.VIBRATOR_SERVICE); n.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { vib.vibrate(15); dialog.dismiss(); } }); p.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { vib.vibrate(20); dialog.dismiss(); task.run(); } }); } //customize text style bold italic.... public SpannableString bold(String s) { SpannableString spanString = new SpannableString(s); spanString.setSpan(new StyleSpan(Typeface.BOLD), 0, spanString.length(), 0); spanString.setSpan(new UnderlineSpan(), 0, spanString.length(), 0); // spanString.setSpan(new StyleSpan(Typeface.ITALIC), 0, // spanString.length(), 0); return spanString; } 

    }

    Вот раскладка xml

                    

    Любой, кто пытается сделать это внутри fragmentа (используя библиотеку поддержки, т.е. pre API 11), должен пойти следующим образом:

     public class LoadingDialogFragment extends DialogFragment { public static final String ID = "loadingDialog"; public static LoadingDialogFragment newInstance() { LoadingDialogFragment f = new LoadingDialogFragment(); return f; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { StyleAlertDialog adb = new StyleAlertDialog(getActivity(), R.style.Your_Style); adb.setView(getActivity().getLayoutInflater().inflate(R.layout.fragment_dialog_layout, null)); return adb; } private class StyleAlertDialog extends AlertDialog { protected StyleAlertDialog(Context context, int theme) { super(context, theme); } } } 

    @Rflexor дал мне толчок расширить AlertDialog и разоблачить конструктора

    Решение Arve Waltin выглядит хорошо, хотя я еще не тестировал его. Существует другое решение в случае, если у вас возникли проблемы с тем, чтобы это сработало … Расширьте AlertDialog.Builder и переопределите все методы (например, setText , setTitle , setView и т. Д.), Чтобы не устанавливать текст / заголовок / просмотр фактического диалога, но для создания нового представления в диалоговом окне «Диалог» все делается там. Тогда вы можете свободно стилизовать все, что захотите.

    Чтобы уточнить, что касается родительского classа, параметр View установлен, и ничего больше.

    Что касается вашего расширенного расширенного classа, все это делается в этом представлении.

    Для пользовательского диалога:

    просто вызовите super(context,R.style.

    ) вместо super(context) в конструкторе диалога

     public class MyDialog extends Dialog { public MyDialog(Context context) { super(context, R.style.Theme_AppCompat_Light_Dialog_Alert) } } 

    Для AlertDialog:

    Просто создайте alertDialog с помощью этого конструктора:

      new AlertDialog.Builder( new ContextThemeWrapper(context, android.R.style.Theme_Dialog)) 

    Это можно сделать просто с помощью setView () Builder. Вы можете создать любое представление по вашему выбору и подать в строитель. Это работает хорошо. Я использую пользовательский TextView, который визуализируется диалоговым построителем. Я не устанавливаю сообщение, и это пространство используется для рендеринга моего custome textview.

     AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Title"); builder.setMessage("Description"); builder.setPositiveButton("OK", null); builder.setNegativeButton("Cancel", null); builder.show(); 
    Давайте будем гением компьютера.