2016-10-29 4 views
5

Я борюсь с изменением цвета ТЕКСТА в диалогах AppCompat Dialog.AppCompatDialog: Невозможно изменить цвет текста

Мое приложение использует тему DARK (Theme.AppCompat.NoActionBar), но для диалогов я хочу тему LIGHT. Я использую Build Tools, Support Library и compileSdkVersion до 25, это имеет значение.

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

Я пытался несколько десятков решений в подобных вопросах здесь в SO, как:

1) Простой один: На ​​styles.xml:

<!-- Application theme. --> 
<style name="AppTheme" parent="AppBaseTheme"> 
    <item name="alertDialogTheme">@style/AppCompatAlertDialogStyle</item> 
    <item name="android:alertDialogTheme">@style/AppCompatAlertDialogStyle</item> 
</style> 

<style name="AppCompatAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert"> 
    <!-- ignored !!!! --> 
    <item name="colorPrimary">#ff0000</item> 
    <!-- ignored !!!! --> 
    <item name="colorPrimaryDark">#ff0000</item> 
    <!-- ignored !!!! --> 
    <item name="colorAccent">#ff0000</item> 
    <!-- ignored !!!! --> 
    <item name="android:textColorPrimary">#F040FF</item> 
    <!-- ignored !!!! --> 
    <item name="android:textColor">#F040FF</item> 

</style> 

С помощью этого решения, то фон и кнопки стиля от AppCompat.Light.Dialog.Alert ТОРМОЗ, но не цвет текста, как вы можете видеть на скриншоте:

enter image description here

2) вручную с указанием стиля на Creation AlertDialog:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppCompatAlertDialogStyle); 
    LayoutInflater inflater = getActivity().getLayoutInflater(); 
    View hostView = mHostView = inflater.inflate(layoutId, null); 

Такая же проблема. Светлый фон, Световой текст.

3) Использование ContextWrapper:

ContextThemeWrapper ctw = new ContextThemeWrapper(getActivity(), R.style.AppCompatAlertDialogStyle); 
    AlertDialog.Builder builder = new AlertDialog.Builder(ctw); 

Ничего :(То же самое происходит

4) вручную указав другие экзотические константы я наткнулся на много постов здесь в SO, как

Theme_DeviceDefault_Light_Dialog_Alert 
THEME_DEVICE_DEFAULT_LIGHT 

Это была отчаянная попытка, но в любом случае текст не изменяется

5) Задание стиля во фрагменте, а не в диалоговом

Dialog_Meta newFragment = new Dialog_Meta(); 
    newFragment.setStyle(DialogFragment.STYLE_NORMAL, R.style.AppCompatAlertDialogStyle); 
    newFragment.show(fragmentManager, TAG); 

я использовал это время раствор назад в очень старой версии API, не могу вспомнить, что была проблема , но в любом случае не решает проблему :(

Может ли кто-нибудь сказать мне, что происходит?

+0

Просто, чтобы быть уверенным: вы используете 'android.support.v7.app.AlertDialog', а не' android.app.AlertDialog', да? –

+0

Спасибо за подсказку. Да, я использую v7.app.AlertDialog! – rupps

+0

О, хорошо, я думаю, что вижу причину. Вы устанавливаете свой собственный 'View' на' AlertDialog', так что тема не будет применяться к этим 'View's. Вы можете комбинировать # 2 и # 3 с манжетой, а вместо 'getActivity() использовать' LayoutInflater.from() 'ContextThemeWrapper'. GetLayoutInflater()'. –

ответ

2

Проблема заключается в обычном View, который вы устанавливаете на AlertDialog. Хотя вы установили определенную тему для AlertDialog s в целом, то View раздувается темой Activity, которая не имеет этих переопределенных значений атрибутов цвета.

Существует несколько способов решить эту проблему.

• Создать ContextThemeWrapper Вокруг Activity «s Context с обычаем R.style и получить LayoutInflater.from() что.

ContextThemeWrapper ctw = new ContextThemeWrapper(getActivity(), R.style.AppCompatAlertDialogStyle); 
LayoutInflater inflater = LayoutInflater.from(getActivity()); 
View hostView = mHostView = inflater.inflate(layoutId, null); 
... 

• Как обнаружен О.П., rupps, то AlertDialog.Builder уже будет alertDialogTheme обернутый на Context он дал, и метод его getContext() возвратит соответствующий ContextThemeWrapper, который может быть использован для Inflater ,

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
LayoutInflater inflater = LayoutInflater.from(builder.getContext()); // THIS IS THE KEY 
View hostView = mHostView = inflater.inflate(layoutId, null); 
... 

Из документации Google о AlertDialog.Builder 'getContext() метода s:

/** 
* Returns a {@link Context} with the appropriate theme for dialogs created by this 
* Builder. 
* Applications should use this Context for obtaining LayoutInflaters for inflating views 
* that will be used in the resulting dialogs, as it will cause views to be inflated with 
* the correct theme. 
* 
* @return A Context for built Dialogs. 
*/ 
public Context getContext() { 
    ... 

• темы может быть установлен в качестве атрибута на корне View из Dialogandroid:theme' s макета.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    android:theme="@style/AppCompatAlertDialogStyle"> 
    ... 

• Вместо обращения инфляция себя, ID компоновщика могут быть переданы в Builder «s setView() вызов, и он будет раздут alertDialogTheme.

С помощью этого метода, однако, объекты View из макета будут недоступны до тех пор, пока не отобразится Dialog. В DialogFragment это будет в методе onStart().

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) { 
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
    builder.setView(R.layout.dialog); 
    return builder.create(); 
} 

@Override 
public void onStart() { 
    super.onStart(); 

    final Dialog dialog = getDialog(); 
    dialog.findViewById(R.id.dialog_button).setOnClickListener(...); 
    ... 
} 
+0

Интересным побочным эффектом этого является то, что этот вид (и его потомки) 'getContext()' вернет «ContextThemeWrapper», обертывающий исходный контекст. Я обнаружил это, потому что я использовал контекст для «Активность» в некоторых кликах. Поэтому в моем случае мне пришлось использовать 'getBaseContext()' в некоторых местах, чтобы получить исходный контекст. – rupps

+0

Да, это имеет смысл. Вы уверены, что вам нужно использовать 'Context' из этих' View's?У вас должен быть доступ к 'getActivity()' в любом месте вашего класса DialogFragment. –

+1

Да, вы правы ... Проблема в том, что мой диалог - это общая оболочка для представлений, которые иногда используются внутри диалога, но также и в обычных макетах в случае больших экранов. Во всяком случае, это краевой корпус с простым решением. Спасибо за подсказку, хотя! – rupps

 Смежные вопросы

  • Нет связанных вопросов^_^