私は少なくともapi 10をサポートしたいのですが、自分の好みをうまくスタイルできるようにしたいです。ヘッダーを持つことができるようにしたい(またはPreferenceScreen
sを表示したい)。 PreferenceActivity
のカラーリングで完全にサポートされていないAppCompat
は適合しないようです。したがって、AppCompatActivity
とPreferenceFragmentCompat
を使用しようとしています。
public class Prefs extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null)
getSupportFragmentManager().beginTransaction()
.replace(Android.R.id.content, new PreferencesFragment())
.commit();
}
public static class PreferencesFragment extends PreferenceFragmentCompat {
@Override public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
@Override
public void onDisplayPreferenceDialog(Preference preference) {
// the following call results in a dialogue being shown
super.onDisplayPreferenceDialog(preference);
}
@Override public void onNavigateToScreen(PreferenceScreen preferenceScreen) {
// I can probably use this to go to to a nested preference screen
// I'm not sure...
}
}
}
次に、フォントの選択を提供するカスタム設定を作成します。 PreferenceActivity
を使用すると、簡単に
import Android.preference.DialogPreference;
public class FontPreference extends DialogPreference {
public FontPreference(Context context, AttributeSet attrs) {super(context, attrs);}
@Override protected void onPrepareDialogBuilder(Builder builder) {
super.onPrepareDialogBuilder(builder);
// do something with builder and make a Nice cute dialogue, for example, like this
builder.setSingleChoiceItems(new FontAdapter(), 0, null);
}
}
このようなxmlを使用して表示します
<my.app.FontPreference Android:title="Choose font" Android:summary="Unnecessary summary" />
しかし現在、Android.support.v7.preference.DialogPreference
にはonPrepareDialogBuilder
はありません。代わりに、PreferenceDialogFragmentCompat
に移動しました。その使用方法に関する情報はほとんど見つかりませんでしたが、xmlから表示する方法がわかりません。 v14設定フラグメントには次のコードがあります。
public void onDisplayPreferenceDialog(Preference preference) {
...
final DialogFragment f;
if (preference instanceof EditTextPreference)
f = EditTextPreferenceDialogFragment.newInstance(preference.getKey());
...
f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
}
Android.support.v7.preference.DialogPreference
をサブクラス化し、onDisplayPreferenceDialog
に同様のコードを使用してダミーのFontPreferenceFragment
をインスタンス化してみましたが、次の例外で失敗します。
Java.lang.IllegalStateException: Target fragment must implement TargetFragment interface
この時点で、私はすでに混乱の奥深くにいるので、これ以上掘り下げたくありません。 Googleはこの例外について何も知りません。とにかく、この方法は複雑すぎるようです。では、Android.support.v7.preferenceライブラリを使用してカスタム設定を作成する最良の方法は何ですか?
重要な注意:現在(v7ライブラリのv23.0.1)、 'PreferenceThemeOverlay'で多くのテーマの問題がまだあります( この問題 )。たとえばLollipopでは、Holoスタイルのカテゴリヘッダーが作成されます。
苛立たしい数時間の後、私はついにカスタムv7プリファレンスを作成することに成功しました。独自のPreference
を作成することは、必要と考えるよりも難しいようです。時間がかかることを確認してください。
最初は、なぜ各優先タイプにDialogPreference
とPreferenceDialogFragmentCompat
の両方が見つかるのか疑問に思われるかもしれません。結局のところ、1つ目は実際の設定で、2つ目は設定が表示されるDialogFragment
です。残念ながら、サブクラスboth そのうちの。
心配しないでください。コードを変更する必要はありません。いくつかのメソッドを再配置する必要があるだけです:
setTitle()
またはpersist*()
など)はDialogPreference
クラスにあります。onBindDialogView(View)
&onDialogClosed(boolean)
)はPreferenceDialogFragmentCompat
に移動されました。あなたはあなたが既存のクラスを最初のものを拡張したいと思うかもしれません、そうすればあなたは私が思うに多くを変える必要がないのです。オートコンプリートは、不足しているメソッドを見つけるのに役立ちます。
上記の手順が完了したら、これらの2つのクラスを一緒にバインドします。 xmlファイルでは、preference-partを参照します。ただし、Androidは、カスタム設定が必要なときにどのFragment
を膨らませる必要があるかをまだ認識していません。そのため、onDisplayPreferenceDialog(Preference)
をオーバーライドする必要があります:
@Override
public void onDisplayPreferenceDialog(Preference preference) {
DialogFragment fragment;
if (preference instanceof LocationChooserDialog) {
fragment = LocationChooserFragmentCompat.newInstance(preference);
fragment.setTargetFragment(this, 0);
fragment.show(getFragmentManager(),
"Android.support.v7.preference.PreferenceFragment.DIALOG");
} else super.onDisplayPreferenceDialog(preference);
}
また、DialogFragment
は「キー」を処理する必要があります。
public static YourPreferenceDialogFragmentCompat newInstance(Preference preference) {
YourPreferenceDialogFragmentCompat fragment = new YourPreferenceDialogFragmentCompat();
Bundle bundle = new Bundle(1);
bundle.putString("key", preference.getKey());
fragment.setArguments(bundle);
return fragment;
}
これでうまくいくはずです。問題が発生した場合は、既存のサブクラスを調べて、Androidがどのように解決したかを確認してください(Android Studio:クラスの名前を入力してCtrl + b逆コンパイルされたクラスを表示します。
Support Preferenceライブラリを拡張するカスタム設定クラスを作成する方法を詳細に説明する優れたチュートリアルとGithubプロジェクトがあります。
https://medium.com/@JakobUlbrich/building-a-settings-screen-for-Android-part-3-ae9793fd31ec -"Building an Android設定画面(パート3)」、Jakob Ulbrich作
https://github.com/jakobulbrich/preferences-demo -サンプルAndroid Githubのプロジェクト
重要な点は次のとおりです。
設定行がクリックされたときのダイアログの起動を制御するカスタムPreferenceDialogFragmentCompat
が必要になります。また、onBindDialogView()
でダイアログのビューを構成します。
設定画面で、onDisplayPreferenceDialog()
をオーバーライドして、カスタムPreferenceDialogFragmentCompat
を起動します。
ダイアログレイアウトを含むカスタムDialogPreference
が必要になります。このDialogPreference
をXML設定ファイルに追加します。
例外は、FontPreferenceFragment
が DialogPreference.TargetFragment を実装していない場合に発生します。フラグメントがそのインターフェースを実装していることを確認する必要があります。