Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何刷新PreferenceActivity以显示设置中的更改?_Android_Refresh_Settings_Preferenceactivity - Fatal编程技术网

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

Android 如何刷新PreferenceActivity以显示设置中的更改?,android,refresh,settings,preferenceactivity,Android,Refresh,Settings,Preferenceactivity,基于以下代码,您能告诉我如何刷新PreferenceActivity窗口以立即显示设置中的更改吗?例如:用户点击主蜂鸣切换复选框为true(勾选),我希望用户立即看到其他设置,如ChimeOn15Past复选框也为true(勾选) 在PreferenceChange上执行并从此处切换相关性能。要“刷新”整个活动,您需要finish()并重新启动它 尼古拉的回答是正确的。我只想在这里添加一些代码来更清楚地说明他的观点 private CheckBoxPreference mOn15Past; pr

基于以下代码,您能告诉我如何刷新PreferenceActivity窗口以立即显示设置中的更改吗?例如:用户点击主蜂鸣切换复选框为true(勾选),我希望用户立即看到其他设置,如ChimeOn15Past复选框也为true(勾选)


在PreferenceChange上执行
并从此处切换相关性能。要“刷新”整个活动,您需要
finish()
并重新启动它

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

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
的设计目的不是在启动后从持久性存储中刷新其值。与其像在代码中那样使用
SharedReferences.Editor
来修改和提交其他更改,不如将这些更改添加到本地
PreferenceManager
对象中,该对象将由
PreferenceActivity
在其正常生命周期中提交。

而不是

finish();
startActivity(getIntent());
我更喜欢以下代码:

setPreferenceScreen(null);
addPreferencesFromResource(R.xml.preferences);
这也将重置显示,但不包括整个完成过程及其后果。 另外,此代码与
PreferenceActivity
PreferenceFragment
配合使用也很好

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


编辑:
setPreferenceScreen
PreferenceActivity
(仍在工作)中被弃用,但不在
PreferenceFragment
中经过一天的斗争,我发现了这个问题。
这适用于多个级别的首选项

父项是首选项屏幕,其中包含您尝试更新的首选项。 由于设置屏幕显示为对话框,您可以从对话框中获取listview,然后告诉它的适配器更新子对象

我发现R.id.list在旧款手机上不可用,但它可以工作

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

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

从文档中:

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


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

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

使用这种方法,您不会失去ListView的位置。

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

onCreate(null);

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

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

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

我成功地编写了一个方法,它实际上非常简单,不需要使ListView无效或任何情况。此方法调用
公共视图组removeView(视图视图)
查看请求布局()
查看forceLayout()
查看组addView(视图视图)
,最后调用创建时的
片段(Bundle savedInstanceState)
方法,带有一些空检查和一个
最终视图
临时变量,用于在删除视图时存储实际视图

这个方法还是很新的,我会在接下来的两天里对它进行一些调整和改进,但它的工作原理是完美的,没有任何副作用。由于我编写的持有代码的类更改了整个rom的实际首选项标题和摘要文本样式(这就是我添加的选项的要点),我还添加了一个公共构造函数,它包含位于首选项样式屏幕下方的活动堆栈中的活动类,以便可以同时更新它们。我很可能会将这个新方法移动到frameworks视图类中,这样它就可以在系统范围内使用

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) {
    }
}
视图变量本身最初在类初始化中设置,并在创建视图的
视图(LayoutInflater inflater,ViewGroup parent,Bundle savedInstanceState)
和创建视图的
视图(view 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)之前的变量。

然后在
onCreate(Bundle savedInstanceState)
中初始化变量:

调用my Demened类以重新加载其视图在my
reloadView(view view view)
方法中完成,但用于进行调用的变量视图是在调用之前设置的视图变量,设置为null:

View tmp = null;
mDemented.reLoadView(tmp);
我的Demened类检查方法调用中包含的视图是否为null,如果为null,则将其设置为本地化视图变量,以便该方法可以处理局部变量:

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)中定义的视图组。:

视图变量在视图创建时设置(视图视图,捆绑包保存状态)


希望这能帮助一些人,因为这是一个我在这里反复看到的问题,我还没有找到一个基本上不涉及多个类作为UTIL的解决方案。如果任何人有任何简化的意见或随意评论的建议。

在您提交对SharedReferences的更改后,我认为您应该打电话。关于它的文档:

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

这将刷新UI,以显示
private DEMENTED mDemented;
mDemented = new DEMENTED();
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
    mViewGroup = parent;
    mView = view;