1

2 つの異なるアクティビティから呼び出される共有設定を実装しようとしています。設定の 1 つは、アクティビティの 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 は別のアクティビティの xml レイアウト ファイルで定義されているため、このコードが機能するとはまったく予想していませんでした。ご想像のとおり、btnClear にアクセスしようとすると、共有設定が変更されたコードで null ポインター例外が発生します。しかし、奇妙なことは、それに関する他のすべてが正しく機能することです (?!)。つまり、アプリを再起動すると、設定チェック ボックスが変更され、対応するコードが実行されます。

実際の問題は、2 つの異なるアクティビティから設定を呼び出し、そのうちの 1 つの変数を変更するという単純な目標をサポートする設定コードをどのように設定すればよいかということです。どうもありがとう。

編集>> 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

実際の問題は、2 つの異なるアクティビティから設定を呼び出し、そのうちの 1 つの変数を変更するという単純な目標をサポートする設定コードをどのように設定すればよいかということです。どうもありがとう。

あなたの質問 (および提供されたコード スニペット) を正しく解釈した場合、PreferenceActivity他の (実行中の可能性がある) アクティビティ内で行われた変更を「プッシュ」しようとしているように見えます。もしそうなら、おそらく物事が逆になっているでしょう。設定の変更をプッシュしようとする代わりに、アクティビティ内からそれらの値を「プル」する必要があります。

言い換えれば、現在持っているようなコードを書かないでください:

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

あなた自身が正しく述べたように(そして経験的に確立された)、現在の の一部ではないレイアウトのウィジェットにアクセスすることはできませActivityPreferenceActivity。設定は、データとアプリの状態を永続的に保存するための中心的な媒体として扱う必要があります。美しさは、参照さえあれば、どこからでも設定にアクセスできることですContext

したがって、上記のように変更をプッシュしようとする代わりにPreferenceActivity、変更が保存されていることを確認するだけで済みます。それが完了したら、設定から保存された値を要求することにより、それが属する(または)btnClear内からの可視性を簡単に切り替えることができます。ActivityFragment

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

たとえば、これを の中に置くことができonCreate(...)ますActivityが、すでに作成されている可能性のある の可視性とスタックを再評価する必要がある場合は、Activity単純に に移動できますonResume()

于 2012-04-27T06:56:31.433 に答える