4
  1. テキスト ファイルを読み取って解析することで、新しい設定セットを読み込みます。
  2. そこで見つけた各設定について、値を抽出し、対応する設定を更新します (CheckPreference、ListPreference、EditTextPreference のいずれであっても)。
  3. これはすべて、設定フラグメントから行われます。変更を行っている間、設定画面が表示されていることを意味します。
  4. プログラムで値を変更したため ( editor().commit)、onSharedPreferenceChange() はトリガーされません。

そのため、後で次のコードを使用してすべての設定を更新します。

private void refreshPreferences() {
    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
    for(int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
        onSharedPreferenceChanged(sp, getPreferenceScreen().getPreference(i).getKey());
    }
}

それは完全に機能します。同じ結果を達成するすべての設定を無効にするシステムコールが存在するかどうかは疑問です( onSharedPreferenceChanged() への自動呼び出し)

私は肛門ではありません。OSによって呼び出されるはずのメソッドを手動で呼び出すのが好きではありません。

編集
これは、設定を変更する私の現在のコードです。以前にエディターで変更しようとしましたが、 onSharePreferncesChanged() 呼び出しも生成していませんでした。
ソース: ファイルから読み取られた複数行の文字列です

private enum Type { INT, BOOLEAN, EDITTEXT, LIST }; 

private void loadPreference(int key, char [] source, Type t) {
    String s = new String(source);
    Log.i(TAG, "+ loadPreference(key:" + key + ", source:(" + s + "), t:" + t + ")");
    String sKey = getText(key).toString();
    Matcher m;
    Preference p = findPreference(sKey);
    switch( t ) {
    case BOOLEAN:
        m = Pattern.compile("(?m)^" + sKey + "=\"(true|false)\"$").matcher(s);
        if( m.find() ) ((CheckBoxPreference)p).setChecked(m.group(1).equals("true"));
        break;
    case INT:
        m = Pattern.compile("(?m)^" + sKey + "=\"(\\d+)\"$").matcher(s);
        if( m.find() ) ((EditTextPreference)p).setText(m.group(1));
        break;
    case EDITTEXT:
        m = Pattern.compile("(?m)^" + sKey + "=\"(.*)\"$").matcher(s);
        if( m.find() ) ((EditTextPreference)p).setText(m.group(1));
        break;
    case LIST:
        m = Pattern.compile("(?m)^" + sKey + "=\"(\\d+)\"$").matcher(s);
        if( m.find() ) ((ListPreference)p).setValueIndex(Integer.valueOf(m.group(1)));
        break;
    default:
    }
    Log.i(TAG, "- loadPreference()");
}

public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    Log.i(TAG, "+ onSharedPreferenceChanged(prefs:" + prefs + ", key:" + key + ")");
    if( key != null ) {
        updatePreference(prefs, key);
        updateSummary(findPreference(key));
    } else {
        Log.e(TAG, "Preference without key!");
    }
    Log.i(TAG, "- onSharedPreferenceChanged()");
}

@Override
public void onResume() {
    Log.i(TAG, "+ onResume()");
    super.onResume();
    // Set up a listener
    getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    Log.i(TAG, "- onResume()");
}

@Override
public void onPause() {
    Log.i(TAG, "+ onPause()");
    super.onPause();
    // Unregister the listener
    getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    Log.i(TAG, "- onPause()");
}
4

2 に答える 2

4

これを実現するためのガイドラインに準拠した方法は、を使用することOnSharedPreferenceChangeListenerです。

あなたの質問のポイント4で、あなたは言います

プログラムで値を変更するため、onSharedPreferenceChange()はトリガーされません。

これは、設定の変更方法によって異なります。あなたのポイント2では、あなたは言います

そこで見つけた設定ごとに、値を抽出し、対応する設定を更新します...

次のように、設定エディタを使用して変更をコミットしてください。

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = sp.edit();
editor.putString("key","value"); // your updated setting
editor.commit();

他のクラスがを適切に実装し、デフォルトOnSharedPreferenceChangeListenerを呼び出して登録している場合は、メソッドでこれらの変更をリッスンできるはずです。registerOnSharedPreferenceChangeListener(this)SharedPreferencesonSharedPreferenceChanged()

少なくとも、設定に関する開発ガイドの記事が示唆していることであり、私は同様の方法で(「プログラムで」設定を変更して)正常に実装しました。

更新された回答:
あなたのコメントは上記が機能しないと言っているので、私は自分のコードをもう一度調べました。確かに、私はあなたが別のクラスからこれを達成したいと思ってあなたの質問を間違えました。

PreferenceFragment(またはPreferenceActivity)を使用している場合は、インターフェイスを実装することできますが、現在のに表示されている設定に登録してください。ベストプラクティスは、電話で登録することですOnSharedPreferenceChangeListenerPreferenceScreenonResume()

getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);

その後、登録を解除しonPause()ます:

getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);

前に説明したように、あなたはあなたのその時の好みの変更を受け取りonSharedPreferenceChanged()ますPreferenceFragment。これは(今では実際に)私のコードで機能する方法です。

于 2013-02-18T00:32:33.810 に答える