web-dev-qa-db-ja.com

PreferenceActivityを更新して設定の変更を表示するにはどうすればよいですか?

次のコードに基づいて、設定の変更をすぐに表示するためにPreferenceActivityウィンドウを更新する方法を教えてください。例:ユーザーがマスターチャイムのトグルチェックボックスをtrue(チェック済み)にタップすると、ChimeOn15Pastチェックボックスなどの他の設定もtrue(チェック済み)になっていることをすぐに確認できます

SharedPreferences.Editor prefEditor = clockSettings.edit(); // Allow the settings to be changed.

if (booleanMasterChimeToggle == true) {
    prefEditor.putBoolean("ChimeOnTheHour", true);
    prefEditor.putBoolean("ChimeOn15Past", true);
    prefEditor.putBoolean("ChimeOn30Past", true);
    prefEditor.putBoolean("ChimeOn45Past", true);

    strNotifyMessage = "Full chiming has now been set.";

} else {
    prefEditor.putBoolean("ChimeOnTheHour", false);
    prefEditor.putBoolean("ChimeOn15Past", false);
    prefEditor.putBoolean("ChimeOn30Past", false);
    prefEditor.putBoolean("ChimeOn45Past", false);

    strNotifyMessage = "Full chiming has now been disabled.";
}
28
Emad-ud-deen

ニコライの答えは正しいです。彼のポイントをより明確に説明するために、ここにコードを追加したいだけです。

private CheckBoxPreference mOn15Past;
private CheckBoxPreference mOn30Past;
private CheckBoxPreference mOn45Past;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Load the preferences from an XML resource
    addPreferencesFromResource(R.xml.preferences);

    mOn15Past = (CheckBoxPreference) findPreference("ChimeOn15Past");
    mOn30Past = (CheckBoxPreference) findPreference("ChimeOn30Past");
    mOn45Past = (CheckBoxPreference) findPreference("ChimeOn45Past");

    final Preference chimeMaster = findPreference("ChimeMaster");
    chimeMaster.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newVal) {
            final boolean value = (Boolean) newVal;
            mOn15Past.setChecked(value);
            mOn30Past.setChecked(value);
            mOn45Past.setChecked(value);
            return true;
        }

    });
}

つまり、PreferenceActivityは、いったん開始されると、永続ストレージから値を更新するようには設計されていません。コードで行ったようにSharedPreferences.Editorを使用して追加の変更を変更およびコミットする代わりに、PreferenceManagerによってコミットされるローカルPreferenceActivityオブジェクトに変更を加えることをお勧めします通常のライフサイクル。

29
Joe

の代わりに

finish();
startActivity(getIntent());

私は次のコードを好みます:

setPreferenceScreen(null);
addPreferencesFromResource(R.xml.preferences);

これにより表示もリセットされますが、finishプロシージャ全体とその結果は含まれません。さらに、このコードはPreferenceActivityPreferenceFragmentでうまく機能します。

これは、たとえばロケール値を動的に変更する場合に役立ちます。この場合、タイトルと値を完全に再ロードする必要があるため、マネージャーでの作業では不十分です。

編集:setPreferenceScreenPreferenceActivityで廃止予定です(まだ機能しています)PreferenceFragmentにはありません

40
Solostaran14

リストのすべてのアイテムを一度に更新する簡単な方法があります。次のようにしてください:

getPreferenceScreen().removeAll();
addPreferencesFromResource(R.xml.preferences);

このアプローチでは、ListViewの位置を失うことはありません。

13

onPreferenceChangeを実装し、そこから関連するパフォーマンスを切り替えます。アクティビティ全体を「更新」するには、finish()を使用して再起動する必要があります。

3
Nikolay Elenkov

これを1日間戦った後、私はこれを理解しました。
これは、複数レベルの設定用です。

 更新しようとしている設定を保持する設定画面です。

設定画面はダイアログとして表示されるので、ダイアログからリストビューを取得し、アダプターに更新を指示できます 

PreferenceScreen parent  // The screen holding the child
PreferenceScreen child   // The entry changing

child.setSummary(isEnabled?"Enabled":"Not Enabled");
ListView v = (ListView)parent.getDialog().findViewById(Android.R.id.list);
BaseAdapter ba = (BaseAdapter)v.getAdapter();
ba.notifyDataSetChanged();

古い電話ではR.id.listが利用できないことがわかりましたが、これは機能します

    ListAdapter adapter = parent.getRootAdapter();
    if (adapter instanceof BaseAdapter) {
        ((BaseAdapter)adapter).notifyDataSetChanged();
    }
1

単にonCreateメソッドを呼び出すことができます。必要に応じて、onStartメソッドとonResumeメソッドを呼び出すことができます。

onCreate(null);

この方法で問題を解決しました。

1
Arda Ç.

このクラスは、単純な設定画面を示します。それはあなたを助けるかもしれません。

public class PreferenceActivitySettings extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
        private SharedPreferences preferences;
        @SuppressWarnings("deprecation")
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.settings);
            preferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
            preferences.registerOnSharedPreferenceChangeListener(this);
        }

        @SuppressWarnings("deprecation")
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            setPreferenceScreen(null);
            addPreferencesFromResource(R.xml.settings);
        }
    }
0
Vinil Chandran

実際には非常にシンプルで、ListViewsなどの状況を無効にする必要のないメソッドを作成することができました。このメソッドは、public ViewGroup removeView(View view)View requestLayout()View forceLayout()ViewGroup addView(View view)を呼び出し、最後にいくつかのFragment OnCreate(Bundle savedInstanceState)メソッドを呼び出しますnullチェックと、ビューが削除されたときに実際のビューを格納するfinal View一時変数。

この方法はまだ非常に新しいので、今後2日間で少し調整して調整しますが、強打の副作用がないため、問題なく機能します。コードを保持している私が作成したクラスは、ROM全体の実際の設定のタイトルと要約テキストのスタイルを変更するため(追加したオプションの全体的なポイントでした)、次のクラスであるパブリックコンストラクターも追加しました。同時に更新できるように、設定スタイル画面の下のアクティビティスタックにあるアクティビティ。ほとんどの場合、この新しいメソッドをフレームワークビュークラスに移動して、システム全体で使用できるようにします。

public void reLoadView(View view) {
    if (view == null) {
        view = mView;
        Log.i(TAG, "The current View is: " + view);
    }
    final View tmpView = view;
    try {
        setStyleChanged(1);
        setReset(0);
        Log.i(TAG, "The Temporary View is: " + tmpView);
        Log.i(TAG, "The current View is: " + mView);
        Log.i(TAG, "The current ViewGroup is: " + mViewGroup);
        if (mView != null) {
            if (mViewGroup != null) {
                mActivity.runOnUiThread(new Runnable() {
                    @Override 
                    public void run() {
                        mViewGroup.removeView(mView);
                        mView.requestLayout();
                        mView.forceLayout();
                        mViewGroup.addView(tmpView);
                        onCreate(new Bundle());
                    } 
                });
            }
        }
        View tmp = null;
        mDemented.reLoadView(tmp);
    } catch (Exception e) {
    }
}

ビュー変数自体は、クラスの初期化で最初に設定され、View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)およびView onViewCreated(View view, Bundle savedInstanceState)で初期化および定義されます。ビュー変数自体は、クラスの初期化で最初に設定されます。

private View mView;
private ViewGroup mViewGroup;

private int mLayoutResId = R.layout.preference_list_fragment;//holds the layout reference just to keep it clean
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    View rootView = inflater.inflate(mLayoutResId, parent, false);
    mViewGroup = parent;
    return rootView;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    mView = view;
}

以下のスタックのアクティビティであるPreferenceStyleクラスでは、アプリの任意の場所で初期化できる空のコンストラクターを設定しています。

public class DEMENTED extends SettingsPreferenceFragment implements
        Preference.OnPreferenceChangeListener, View.OnClickListener {

    public DEMENTED() {
         super();
    }

    //other code to do whatever here

私のPreferenceStyleクラスで、DEMENTEDクラスをインポートし、onCreate(Bundle savedInstanceState)の前に変数として設定しました。

private DEMENTED mDemented;

次に、onCreate(Bundle savedInstanceState)で変数を初期化しました。

mDemented = new DEMENTED();

ビューをリロードするための私のDEMENTEDクラスの呼び出しはreloadView(View view)メソッドで行われますが、呼び出しに使用される変数ビューは呼び出しの直前に設定されたビュー変数であり、nullに設定されています。

View tmp = null;
mDemented.reLoadView(tmp);

そして、私のDEMENTEDクラスは、メソッド呼び出しに含まれるViewがnullかどうかを確認し、nullの場合はローカライズされたView変数に設定して、メソッドがローカル変数で作業できるようにします。

public void reLoadView(View view) {
    if (view == null) {
        view = mView;
        Log.i(TAG, "The current View is: " + view);
    }
    //all the other good stuff here

基本的に、これはonCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)で定義されているViewGroupを使用します。

    mViewGroup = parent;

onViewCreated(View view, Bundle savedInstanceState)にビュー変数が設定されています

    mView = view;

これが誰かに役立つことを願っています。これは私がここで何度も繰り返し見た質問であり、utilsとして使用される複数のクラスを含まない基本的な場所にはまだ固い解決策を見つけていないからです。誰かがコメントを簡単にするための提案や、自由にコメントしてください。

0
cphelps76

SharedPreferencesの変更をコミットした後は、 invalidateHeaders() を呼び出すだけでよいと思います。それについての文書:

表示されているヘッダーを変更する必要があるときに呼び出します。その後、新しいリストを取得するためにonBuildHeaders()が呼び出されます。

これにより、UIが更新され、新しい値が表示されます。

0