web-dev-qa-db-ja.com

PreferenceFragmentの個々の設定にAppCompatテーマを適用する

私は自分のPreferenceFragmentに、他のアプリケーションと同じマテリアルベースのテーマとスタイル(AppCompat経由)を持たせることに取り組んできました。すべてのアプリケーション設定を管理するために使用しているPreferenceFragmentを以下に示します。

enter image description here

上のスクリーンショットからわかるように、PreferenceFragmentcolorAccent、およびその他のいくつかの属性を使用して、colorPrimaryをカスタマイズすることができました。 PreferenceFragmentの私のテーマは次のとおりです。

<style
    name="settingsTheme"
    parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/blue_grey_500</item>
    <item name="colorAccent">@color/blue_grey_500</item>
    <item name="Android:textColor">@color/black_text_alt</item>
    <item name="Android:textColorSecondary">@color/black_secondary_text</item>
</style>

ただし、最善を尽くしても、PreferenceFragmentListPreferenceなど、EditTextPreference内の個々の要素にテーマを適用することはできません。すべての設定は、引き続き標準のAppCompatテーマを保持しています。

enter image description here

実際の解決策はありませんが、この問題について説明している2年前の投稿を見つけました: <PreferenceCategory>の<PreferenceScreen>要素にテーマを適用する方法

AppComat V21がリリースされてから、誰かがテーマを設定に正常に適用できるようになったのではないかと思います。そうでない場合、個々の好みにカスタムテーマを適用するために使用できる実行可能な回避策はありますか?

18
Willis

UPDATE:この問題と戦うためにライブラリを作成しました(AppCompat r22を使用): https://github.com/consp1racy/Android- support-preference


ListPreferenceDialogPreferenceを拡張し、このコードを使用してダイアログを作成します。

mBuilder = new AlertDialog.Builder(context)
    .setTitle(mDialogTitle)
    .setIcon(mDialogIcon)
    .setPositiveButton(mPositiveButtonText, this)
    .setNegativeButton(mNegativeButtonText, this);

ご覧のとおり、AlertDialog.Builderコンストラクターには2番目のオプションのint themeパラメーターが付属していません。つまり、ダイアログは、アクティビティのテーマのAndroid:alertDialogTheme属性に含まれるテーマに基づいて作成されます。

次に、次のようにTheme.AppCompat.Dialogから派生するダイアログのカスタムテーマを作成する必要があります。

<style name="Theme.YourApp.Dialog.Alert" parent="Theme.AppCompat.Light.Dialog">
  <item name="Android:windowBackground">@Android:color/transparent</item>
  <item name="Android:windowContentOverlay">@null</item>
  <item name="Android:windowMinWidthMajor">@Android:dimen/dialog_min_width_major</item>
  <item name="Android:windowMinWidthMinor">@Android:dimen/dialog_min_width_minor</item>
  <item name="colorAccent">@color/accent_yourapp</item>
  <item name="colorPrimary">@color/primary_yourapp</item>
  <item name="colorPrimaryDark">@color/primary_dark_yourapp</item>
</style>

問題1:上記のソリューションは、RingtonePreferenceを拡張せず、着信音チューザーを呼び出すため、ListPreferenceでは機能しません。意図しているので、常にシステムに応じてテーマが設定されています。この回答を確認してください: RingtonePreference Theme これを解決済みとしてマークできます。

問題2:AppCompatダイアログにタイトルがありません。そして今のところ私はこれを修正する方法を見つけていません。確かに私は十分に一生懸命探していません。マイナーな問題としてタイトルの欠如を無視しましょう。

問題3:ラジオボタンのドローアブルが変更されていないため、グラフィックがパッシブ状態とアクティブ(色付き)状態の間で一貫性がありません-すべてが色付きです(1つだけではありません) you!re press)またはすべてが灰色です。今、これは本当に迷惑です

問題2と3により、別のルートを取る必要がありました。API14以降のダイアログテーマは次のようになります。

<style name="Theme.MyApp.Dialog.Alert" parent="Android:Theme.DeviceDefault.Light.Dialog.MinWidth">
  <item name="Android:windowBackground">@Android:color/transparent</item>
  <item name="Android:windowContentOverlay">@null</item>
</style>

aPI21 +でこのように

<style name="Theme.YourApp.Dialog.Alert" parent="Android:Theme.DeviceDefault.Light.Dialog.MinWidth">
  <item name="Android:colorPrimary">@color/primary_yourapp</item>
  <item name="Android:colorPrimaryDark">@color/primary_dark_yourapp</item>
  <item name="Android:colorAccent">@color/accent_yourapp</item>
</style>

これらの値は、プラットフォームのソースファイルをクロールすることによって実験的に取得され、十分にテストされています。

重要なのは、信頼できる唯一の解決策は、デバイスのデフォルトのダイアログテーマを使用することであるように思われるということです。ロリポップの前の唯一の選択肢は、明るいまたは暗いバリアントです。 Lollipopでは、これは意図したとおりに機能します。

EDIT:appcompat-v7-r21.1.0以降、マテリアルをテーマにしたバリアントである AppCompatDialog を使用できます。ネイティブAlertDialog

インスタンスの作成には、提供されている AlertDialog.Builder (ネイティブの対応物と混同しないでください)を使用できます。

9
Eugen Pechanec

DialogPreferenceAndroid.app.AlertDialog.Builderを直接使用するため、表示されたダイアログをすべてのAPIレベルのマテリアルデザインダイアログに切り替えることはできません(Android.support.v7.widget.AlertDialog.Builderを使用する必要があります)。

今のところ唯一のオプションは、DialogPreferenceまたはそのサブクラスのダイアログ作成ロジックを拡張してオーバーライドすることです(必要に応じて、リフレクションを使用してプライベートアクセサーを回避します)。これをチェックしてください redditスレッド そしてそのスレッドの作者によって作られた例 AppCompatListPreference

3
hidro

すでに与えられた回答からヒントを得て、マニフェストで設定アクティビティのカスタムテーマを設定しました。これは、表示されるダイアログの周囲の境界線の背景を削除する必要があるためです。これは、API <21の場合にのみ透明な背景を使用します。

AndroidManifest.xml

<application
    Android:name=".MyApplication"
    ...
    Android:theme="@style/AppTheme">
    ...
    <activity
        Android:name=".ui.SettingsActivity"
        ...
        Android:theme="@style/AppTheme.Settings">
    </activity>
</application>

values/style.xml

<!-- Application theme -->
<style name="AppTheme" parent="AppTheme.Base">
    <!-- All customizations that are NOT specific to a particular API-level can go here. -->

</style>

<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="Android:alertDialogTheme">@style/AppTheme.AlertDialog</item>
</style>

<!-- Must be different because of transparent background -->
<style name="AppTheme.Settings" parent="AppTheme.Base">
    <item name="Android:alertDialogTheme">@style/AppTheme.SettingsAlertDialog</item>
</style>

<style name="AppTheme.AlertDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="Android:windowMinWidthMajor">@Android:dimen/dialog_min_width_major</item>
    <item name="Android:windowMinWidthMinor">@Android:dimen/dialog_min_width_minor</item>
    <item name="Android:windowContentOverlay">@null</item>
    <item name="colorAccent">@color/accent_light</item>
    <item name="colorControlActivated">@color/accent_light</item>
    <item name="colorControlHighlight">@color/primary_highlight</item>
</style>

<style name="AppTheme.SettingsAlertDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="Android:windowMinWidthMajor">@Android:dimen/dialog_min_width_major</item>
    <item name="Android:windowMinWidthMinor">@Android:dimen/dialog_min_width_minor</item>
    <item name="Android:windowBackground">@Android:color/transparent</item>
    <item name="Android:windowContentOverlay">@null</item>
    <item name="colorAccent">@color/accent_light</item>
    <item name="colorControlActivated">@color/accent_light</item>
    <item name="colorControlHighlight">@color/primary_highlight</item>
</style>

最後に、values -v21/style.xmlの場合、これをv21ダイアログに入れないと、通常のダイアログになります。トランスペアレント。

<style name="AppTheme.Settings" parent="AppTheme.Base">
    <item name="Android:alertDialogTheme">@style/AppTheme.AlertDialog</item>
</style>

実際、テーマ属性から直接色を設定するのに問題があります:固定色@ color/accent_lightの代わりに?android:colorAccent。

2
Davideas

さまざまなコンポーネントがテーマの色属性をどのように使用するかについて、 この要点 を確認する必要があります。必要な効果を得るには、テーマに次の属性を追加する必要がある場合があります。

<item name="colorControlNormal">@color/x_color</item>
<item name="colorControlActivated">@color/y_color</item>
<item name="colorControlHighlight">@color/z_color</item>
1
dandc87