如何刷新PreferenceActivity以显示设置中的更改?

时间:2011-11-03 23:12:41

标签: android refresh settings preferenceactivity

根据以下代码,您能告诉我如何刷新PreferenceActivity窗口以立即显示设置中的更改吗?例如:用户点击主chime切换复选框为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.";
}

10 个答案:

答案 0 :(得分:39)

而不是

finish();
startActivity(getIntent());

我更喜欢以下代码:

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

这也将重置显示,但没有整个完成程序及其后果。 此外,此代码适用于PreferenceActivityPreferenceFragment

如果您想动态更改区域设置值,这很有趣。在这种情况下,与经理合作是不够的,因为您需要完全重新加载标题和值。

编辑:setPreferenceScreen已弃用PreferenceActivity(仍然有效),但不在PreferenceFragment

答案 1 :(得分:29)

尼古拉的回答是正确的。我只想在这里添加一些代码来更清楚地说明他的观点。

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在其中提交正常生命周期。

答案 2 :(得分:13)

这是一种简单的方法,可以立即刷新列表中的所有项目。只需执行以下操作:

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

通过这种方法,您不会失去ListView的位置。

答案 3 :(得分:3)

实施onPreferenceChange并从那里切换相关的perf。要刷新'整个活动,您需要finish()并重新启动它。

答案 4 :(得分: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();
    }

答案 5 :(得分:1)

您只需调用onCreate方法即可。如果需要,可以调用onStart和onResume方法。

onCreate(null);

我用这种方式解决了我的问题。

答案 6 :(得分:0)

此类表示简单的首选项屏幕。这对你有帮助。

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

答案 7 :(得分:0)

我设法写了一个方法,实际上非常简单,无需使ListViews无效或者无论情况如何。此方法调用public ViewGroup removeView(View view)View requestLayout()View forceLayout()ViewGroup addView(View view),最后调用Fragment OnCreate(Bundle savedInstanceState)方法,并进行一些空检查和{ {1}}临时变量,用于在删除视图时存储实际视图。

这种方法还是很新的,我会在接下来的两天内对它进行一些调整和精炼,但是它没有任何副作用,而且完美无瑕。由于我写的代码持有代码改变了整个rom的实际首选项标题和摘要文本样式(这是我已经添加的选项的全部内容),我还添加了一个公共构造函数是位于首选项样式屏幕下方的活动堆栈中的活动的类,因此可以同时更新它们。我很可能会将这个新方法移动到框架视图类中,以便可以在系统范围内使用它。

final View

视图变量本身最初在类初始化中设置,并在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)

在下面的堆栈中的活动,我的PreferenceStyle类中,我设置了一个空构造函数,可以在应用程序的任何位置进行初始化。

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类中,我导入了DEMENTED类,然后在public class DEMENTED extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener, View.OnClickListener { public DEMENTED() { super(); } //other code to do whatever here 之前将其设置为变量:

onCreate(Bundle savedInstanceState)

然后在private DEMENTED mDemented; 中初始化变量:

onCreate(Bundle savedInstanceState)

调用我的DEMENTED类重新加载其视图是在我的mDemented = new DEMENTED(); 方法中完成的,但用于调用的变量视图是在调用之前设置的View变量,并设置为null:

reloadView(View view)

并且我的DEMENTED类检查方法调用中包含的View是否为null,如果是,则将其设置为本地化的View变量,以便该方法可以使用局部变量:

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

基本上,它使用public void reLoadView(View view) { if (view == null) { view = mView; Log.i(TAG, "The current View is: " + view); } //all the other good stuff here 中定义的ViewGroup:

onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)

和View变量在 mViewGroup = parent;

中设置
onViewCreated(View view, Bundle savedInstanceState)

希望这可以帮助别人,因为这是我一遍又一遍地在这里重复看到的一个问题,我还没有找到一个可靠的解决方案,基本上没有涉及多个类用作utils。如果有人有任何评论建议,以简化或任何随意发表评论。

答案 8 :(得分:0)

将更改提交到sharedPreferences后,我认为您应该只调用invalidateHeaders()。关于它的文档:

  

需要更改正在显示的标题时调用。将导致   在onBuildHeaders()中稍后调用以检索新列表。

这应该刷新UI,以显示新值。

答案 9 :(得分:-1)

如果您的目标是API 11及更高版本,则可以使用invalidateHeaders

来自文档:

  

需要更改正在显示的标题时调用。将导致   在onBuildHeaders()中稍后调用以检索新列表。