1

我正在尝试实现从两个不同的活动中调用的共享首选项。其中一个首选项是一个复选框,它隐藏或公开包含在其中一个活动的 xml 布局文件中的按钮。

此方案使用以下方法实现:

public class MyPreferencesActivity extends PreferenceActivity
    implements OnSharedPreferenceChangeListener { ... }

同样在 MyPreferencesActivity 类中,我的首选项更改代码如下:

@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    Button btnClear = (Button) findViewById(R.id.clearbuttonid);
    if (prefs.getBoolean("Clear User Flag", true))
        btnClear.setVisibility(View.VISIBLE);
    else
        btnClear.setVisibility(View.INVISIBLE);
}

首选项类还具有:

@Override     
protected void onResume() {
    super.onResume();
    getPreferenceScreen().getSharedPreferences().
        registerOnSharedPreferenceChangeListener(this);     
}

...使用 onPause() 类似地取消注册侦听器。

正如所写的那样,我并不期望这段代码能够工作,因为 clearbuttonid 是在不同的 Activity 的 xml 布局文件中定义的。正如您所料,当我尝试访问 btnClear 时,我在共享首选项更改代码中遇到了一个空指针异常。但奇怪的是,它的其他一切都正常工作(?!)。也就是说,当我重新启动应用程序时,首选项复选框已更改,并且已执行相应的代码。

实际问题是:如何设置首选项代码以支持能够从两个不同活动调用首选项并更改其中一个变量的简单目标?非常感谢。

编辑>>根据 Raju 的要求,这里是 logcat:

04-27 00:26:57.989: I/onSharedPreferenceChange(537): Shared preference changed
04-27 00:26:57.989: D/AndroidRuntime(537): Shutting down VM
04-27 00:26:57.989: W/dalvikvm(537): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
04-27 00:26:58.029: E/AndroidRuntime(537): FATAL EXCEPTION: main
04-27 00:26:58.029: E/AndroidRuntime(537): java.lang.NullPointerException
04-27 00:26:58.029: E/AndroidRuntime(537):  at com.xyzzy.prototype.MyPreferencesActivity.onSharedPreferenceChanged(MyPreferencesActivity.java:49)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.app.SharedPreferencesImpl$EditorImpl.notifyListeners(SharedPreferencesImpl.java:455)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.app.SharedPreferencesImpl$EditorImpl.apply(SharedPreferencesImpl.java:365)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.preference.Preference.tryCommit(Preference.java:1339)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.preference.Preference.persistBoolean(Preference.java:1605)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.preference.TwoStatePreference.setChecked(TwoStatePreference.java:79)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.preference.TwoStatePreference.onClick(TwoStatePreference.java:68)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.preference.Preference.performClick(Preference.java:939)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.preference.PreferenceScreen.onItemClick(PreferenceScreen.java:202)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.widget.AdapterView.performItemClick(AdapterView.java:292)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.widget.AbsListView.performItemClick(AbsListView.java:1058)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.widget.AbsListView$PerformClick.run(AbsListView.java:2514)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.widget.AbsListView$1.run(AbsListView.java:3168)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.os.Handler.handleCallback(Handler.java:605)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.os.Handler.dispatchMessage(Handler.java:92)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.os.Looper.loop(Looper.java:137)
04-27 00:26:58.029: E/AndroidRuntime(537):  at android.app.ActivityThread.main(ActivityThread.java:4424)
04-27 00:26:58.029: E/AndroidRuntime(537):  at java.lang.reflect.Method.invokeNative(Native Method)
04-27 00:26:58.029: E/AndroidRuntime(537):  at java.lang.reflect.Method.invoke(Method.java:511)
04-27 00:26:58.029: E/AndroidRuntime(537):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-27 00:26:58.029: E/AndroidRuntime(537):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-27 00:26:58.029: E/AndroidRuntime(537):  at dalvik.system.NativeStart.main(Native Method)
04-27 00:26:58.599: I/dalvikvm(537): threadid=3: reacting to signal 3
04-27 00:26:58.618: I/dalvikvm(537): Wrote stack traces to '/data/anr/traces.txt'
4

1 回答 1

2

实际问题是:如何设置首选项代码以支持能够从两个不同活动调用首选项并更改其中一个变量的简单目标?非常感谢。

如果我正确地解释了您的问题(并提供了代码片段),那么您似乎正在尝试将内部所做的更改“推送”PreferenceActivity到其他(可能正在运行?)活动。如果确实如此,那么您可能已经把事情倒退了。与其试图推动偏好变化,不如从活动中“提取”他们的价值观。

换句话说,不要像现在这样编写代码:

if (prefs.getBoolean("Clear User Flag", true))
    btnClear.setVisibility(View.VISIBLE);
else
    btnClear.setVisibility(View.INVISIBLE);

正如您正确地陈述自己(并且根据经验建立的),您无法访问不属于当前布局的小部件Activity,无论是“常规”布局还是PreferenceActivity. 您应该将首选项视为持久存储数据和应用程序状态的中心媒介。美妙之处在于,只要您有Context参考,您就可以从任何地方访问偏好。

因此,与其像上面那样尝试推送更改,您需要做的PreferenceActivity就是确保存储更改。btnClear完成后,您可以通过从首选项中请求存储的值来简单地从它所属的Activity(或)中切换 的可见性:Fragment

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean visible = prefs.getBoolean("Clear User Flag", true)
btnClear.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);

例如,您可以将其放在onCreate(...)您的 中Activity,但如果您需要重新评估Activity可能已经创建并在堆栈中的可见性,您可以简单地将其移动到 egonResume()中。

于 2012-04-27T06:56:31.433 回答