15

私は少なくともapi 10をサポートしたいと思っています。私は自分の好みをうまくスタイルすることができるようにしたい、私はヘッダーを持つことができるようにしたい(またはPreferenceScreenを表示する)。それはAppCompatによって完全にサポートされていないPreferenceActivityのようだ、フィットしません。だから私はAppCompatActivityPreferenceFragmentCompatを使用しようとしています。android.support.v7.preferenceライブラリを使用してカスタム設定を作成するにはどうすればよいですか?

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); 
    } 
} 

を行うことができ、それ

<my.app.FontPreference android:title="Choose font" android:summary="Unnecessary summary" /> 

を表示するには、このようなXMLを使用しかし、今、android.support.v7.preference.DialogPreferenceにはonPrepareDialogBuilderはありません。代わりに、PreferenceDialogFragmentCompatに移動されました。私はそのことをどのように使うべきかについての情報はほとんど見つけず、xmlからそれを表示する方法はわかりません。

public void onDisplayPreferenceDialog(Preference preference) { 
    ... 

    final DialogFragment f; 
    if (preference instanceof EditTextPreference) 
     f = EditTextPreferenceDialogFragment.newInstance(preference.getKey()); 
    ... 
    f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG); 
} 

Iはandroid.support.v7.preference.DialogPreferenceをサブクラス化し、onDisplayPreferenceDialogダミーFontPreferenceFragmentをインスタンス化するコードの同様の部分を使用するが、それは次の例外で失敗有する試み:V14嗜好断片は、以下のコードを有しています。

java.lang.IllegalStateException: Target fragment must implement TargetFragment interface 

この時点では、私はすでにあまりにも混乱に深く、さらなる掘り起こしたくありません。 Googleはこの例外について何も知らない。とにかく、この方法はあまりにも複雑なようです。だから、android.support.v7.preferenceライブラリを使用してカスタム設定を作成する最良の方法は何ですか?

答えて

28

重要な注意:現在 (v23.0.1 V7ライブラリの) 'PreferenceThemeOverlay' がテーマの問題の多くが残っている(this issueを参照してください)。たとえば、Lollipopでは、ホロスタイルのカテゴリヘッダーになります。

少し時間が過ぎた後、ついにはカスタムv7環境設定を作成することに成功しました。独自のPreferenceを作成することは、必要と思われるよりも難しいようです。だから時間を取るようにしてください。

最初に、お好みのタイプごとにDialogPreferencePreferenceDialogFragmentCompatの両方が見つかるのだろうかと疑問に思うかもしれません。最初のものは実際の環境設定、もう1つはDialogFragmentです。悲しいことに、の両方をサブクラス化する必要があります。です。

心配はいりませんが、コードを変更する必要はありません。あなただけのいくつかのメソッドを再配置する必要があります(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 Studioの場合、クラスの名前を入力し、Ctrl + bを押して非コンパイルクラスを参照してください)。それが役に立てば幸い。

+2

ほぼ完璧なソリューション! onDisplayPreferenceDialogがPreferenceFragmentCompatを継承している嗜好フラグメントでオーバーライドする必要があることを理解するまでにはしばらく時間がかかりました。どうもありがとう! –

+2

これを読んでいる人のための注意:PreferenceDialogFragmentCompat.java:57/58でClassCastExceptionが発生した場合は、bundle.putString( "key"、preference.getKey());上記のように「キー」が表示されます。それ以外の場合、getArguments()。getString(ARG_KEY)はClassCastExceptionで失敗します。 – MCLLC

+0

お持ちの場合は完全な例を投稿してください。私は新しいサポートの設定を実装することに成功しましたが、DialogPreferencesは大事なものです。 Googleは、これに関するドキュメントを提供していません。 –

0

あなたFontPreferenceFragmentDialogPreference.TargetFragmentを実装していない場合に例外が発生します。フラグメントがそのインタフェースを実装していることを確認する必要があります。

+0

これは 'DialogPreference.TargetFragment'を実装しています。しかし、それを実装することで何かが解決されたとしても、それはまだ回避策になります。正しい方法はもっと簡単な方法でなければなりません。 – squirrel

関連する問題