Support.v7.preferenceを使用して、AppCompatアプリの設定を実装しようとしました。 support.v7.preferenceにはネイティブの設定といくつかの重要な違いがあるので、それをいじくるのに数日かかりました。他の人が同じ苦痛を経験する必要がないように、私の発見を共有したいと思いました。
(PreferenceFragmentとAppCompatAcitivityに互換性がない)AppCompatアプリの設定を最適に実装するにはどうすればよいですか?
PreferenceFragment
とAppCompatActivity
AndroidStudioで、File> New Project> ...> SettingsActivityを選択します。このテンプレートでは、_support.v4.Fragment
_または_support.v7.PreferenceFragmentCompat
_と同様に、ネイティブPreferenceFragment
を改造してAppCompatActivity
を操作する回避策を使用します。
AppCompat
アプリ内でネイティブの設定機能を使用できるようになりました。これは、ASテンプレートを使用する場合の迅速なアプローチであり、既存の設定ドキュメントとワークフローをそのまま使用できます。support.v7.preference.PreferenceFragmentCompat
_ with AppCompatActivity
ColorPicker
またはFontPreferences
)では機能しない可能性があります。ソリューション1を使用しないことを選択した場合(2つのうちどちらがより将来性があるかはまだわかりません)、_support.v7.preference
_を使用するときにいくつかの欠点があります。
Solution 2を使用する際の重要な欠点を以下に示します。
依存関係:
_dependencies {
...
compile 'com.Android.support:appcompat-v7:23.1.1'
compile 'com.Android.support:preference-v7:23.1.1'
compile 'com.Android.support:support-v4:23.1.1'
}
_
テーマ:preferenceTheme
をstyles.xmlで定義する必要がありますそれ以外の場合、アプリを実行すると例外が発生します。
_<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>
_
これを7 +/14 +/21 +の異なるスタイルに分割したいかもしれません。この記事の執筆時点では、多くの人がこれがバグだと不満を持っています。利用可能な非常に包括的な答えがあります ここ 。
動作の変更:ネイティブ設定の使用は非常に簡単です:_preferences.xml
_を定義/維持し、addPreferencesFromResource(R.xml.preferences)
PreferenceFragment
内。カスタム設定はDialogPreference
をサブクラス化することで簡単に実行でき、_preferences.xml
_...内で参照するだけで動作します。
残念ながら、_support.v7.preference
_はFragment
の処理に関連するすべてのものを取り除いており、組み込み機能の多くを失っています。 XMLを保守するだけでなく、多くのことをサブクラス化してオーバーライドする必要がありますが、そのすべてが残念ながら文書化されていません。
PreferenceScreens:PreferenceScreens
は、フレームワークによって管理されなくなりました。 _preference.xml
_でPreferenceScreen
を定義すると( docs で説明)、エントリは表示されますが、クリックしても何も起こりません。サブ画面の表示とナビゲートは、あなた次第です。退屈な。
PreferenceFragmentCompat
に_PreferenceFragmentCompat.OnPreferenceStartScreenCallback
_を追加する方法が1つあります(説明は here )。このアプローチはすぐに実装されますが、既存の設定フラグメントのコンテンツを交換するだけです。欠点は、バックナビゲーションがなく、常に「上部」にいるため、ユーザーにとって直感的ではないことです。
別のアプローチ(説明 here )では、期待どおりに戻るナビゲーションを実現するために、バックスタックも管理する必要があります。これは、新しく作成/表示された各フラグメントのルートとしてpreferenceScreen.getKey()
を使用します。
その場合、デフォルトでPreferenceFragments
が透明になり、奇妙に加算されることも考えられます。人々はPreferenceFragmentCompat.onViewCreated()
をオーバーライドして次のようなものを追加する傾向があります
_// Set the default white background in the view so as to avoid transparency
view.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.background_material_light));
_
カスタムDialogPreference:独自の設定を作成することも、ささいなことから退屈なことへと進んでいます。 DialogPreference
には、実際のダイアログを処理するものがすべて含まれているため、削除されました。そのビットは現在PreferenceDialogFragmentCompat
にあります。したがって、両方をサブクラス化し、ダイアログを作成して自分で表示する必要があります( ここ で説明)。
PreferenceFragmentCompat.onDisplayPreferenceDialog()
のソースを見ると、正確に2つのダイアログ設定(EditTextPreference
、ListPreference
)を処理する方法がわかっていることがわかります。 OnPreferenceDisplayDialogCallback
s ...不思議なことに、なぜDialogPreference
のサブクラスを処理する機能がないのでしょうか。
以下は、これらの回避策のほとんどを実装し、libモジュールにボックス化するコードです。
https://github.com/mstummer/extended-preferences-compat.git
主な意図は:
Activity
とPreferenceFragment
を拡張して操作する必要をなくします。 _preference.xml
_が、変更/維持するプロジェクトごとの唯一のファイルになりました。PreferenceScreens
(サブ画面)を処理して表示します。DialogPreference
の分割を解除して、ネイティブの動作を復元します。DialogPreference
のサブクラスを処理して表示します。箱から出しただけで使用できるほどクリーンだとは思わないでください。同様の問題に対処するときにヒントが得られる場合があります。試してみて、何か提案があれば教えてください。
私はこれに対する代替の解決策を持っています。フィードバックが欲しいです。
左上隅に「戻る」ボタンを使用して、preferencefragmentのカスタムレイアウトを作成しました。
まず、 "onCreatePreference"にルートPreferenceScreenを格納します。
root = this.getPreferenceScreen();
次に、上記のようにOnPreferenceStartScreenCallbackを追加し、他のスレッドでフラグメントをサブ画面に移動させますが、「onPreferenceStartScreen」で、戻るボタンも次のように表示されるように設定します。
public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat, PreferenceScreen preferenceScreen) {
preferenceFragmentCompat.setPreferenceScreen(preferenceScreen);
backButton.setVisibility(View.VISIBLE);
return true;
}
最後に、backButtonクリックハンドラー:
setPreferenceScreen(root);
back.setVisibility(View.GONE);
これは私にとってはうまくいくようです。明らかに、バックスタックは機能しませんが、[戻る]ボタンがあるので、それでも問題ありません。
完璧ではありませんが、最悪のAPIを考えると私は満足していると思います。
誰かがこのアプローチに問題があると思ったら聞いてみたいです。