2016-10-29 12 views
5

私はAppCompat DialogFragmentsのTEXTの色を変更するのに苦労しています。AppCompatDialog:テキストの色を変更することができません

My AppはDARKテーマ(Theme.AppCompat.NoActionBar)を使用しますが、ダイアログではLIGHTテーマが必要です。私は、ビルドツール、サポートライブラリ、およびcompileSdkVersionを25に使用しています。それは重要です。

のダイアログで他のすべてを変更することはできますが、暗いテーマには(白い)設定を使用し続けるプライマリおよびアクセント付きのテキストカラーではありません、白白い背景の上にテキスト。

私は好きなので、ここで同様の質問でのソリューションの数十を試してみた:

1)簡単な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> 

enter image description here

:あなたはスクリーンショットで見ることができるよう AppCompat.Light.Dialog.Alertから背景やボタンのスタイルは、テキストの色適用されるが、ではありません

2)手動AlertDialog作成にスタイルを指定する:

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

同じ問題。ライト背景、ライトテキスト。 ContextWrapper使用

3):同じことが起こる:(

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

ああ、私は理由が分かると思う。 'AlertDialog'に独自の' View'を設定しているので、テーマは 'View'には適用されません。カフを外して#2と#3を組み合わせ、 'getActivity()。getLayoutInflater()'の代わりに 'LayoutInflater.from()'を 'ContextThemeWrapper'にすることができます。 –

答えて

2

ここでの問題はViewAlertDialogに設定しているカスタムです。 AlertDialogのテーマを設定しても、ActivityのテーマではViewが膨張していますが、そのテーマはオーバーライドされた色属性値を持っていません。

これを解決するにはいくつかの方法があります。

ActivityContextの周りにR.styleのカスタムを作成し、を取得します。

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

•OP、ruppsによって発見されたとして、AlertDialog.BuilderはすでにContextに包まれalertDialogThemeそれは与えられていますし、そのgetContext()方法はのInflaterのために使用することができる適切なContextThemeWrapper、返されています。 AlertDialog.BuilderのGoogleのドキュメントから

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

ます。■レイアウトのgetContext()方法テーマ•

/** 
* 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() { 
    ... 

DialogのルートViewandroid:theme属性として設定することができます "。むしろインフレを自分で処理するよりも

<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はBuildersetView()コールに渡すことができ、そしてそれはalertDialogThemeで膨張されます。

ただし、この方法では、Dialogが表示されるまで、レイアウトのオブジェクトはViewになりません。 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

これの興味深い副作用は、このView(およびその子孫)の 'getContext()'が元のコンテキストをラップする 'ContextThemeWrapper'を返すということです。私はそれを発見しました。なぜなら、私はいくつかのクリックハンドラーでコンテキストを「アクティビティ」にキャストしていたからです。だから私の場合は、元のコンテキストを取得するためにいくつかの場所で 'getBaseContext()'を使用しなければなりませんでした。 – rupps

+0

ええ、それは理にかなっています。それらの 'View'から' Context'を使う必要がありますか?'DialogFragment'クラスのどこでも' getActivity() 'にアクセスする必要があります。 –

+1

はい、あなたは正しいです...問題は、私のダイアログフラグメントは、ダイアログ内で使用されるビューのための包括的ラッパーであるが、より大きなスクリーンの場合には通常のレイアウトでも使用される。とにかく、それは簡単な解決策との端の場合です。しかし、チップをありがとう! – rupps

関連する問題