1

私は本から例を取得しようとしていますAndroid用のMonoを使用したProfessional Android Programming and .Net/C# (pages 202 to 204) working.

変更リスナーを登録および登録解除するには、次のコード サンプルを示します。

using System;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Preferences;

namespace MonoForAndroidPreferences
{
    [Activity(Label = "User Preferences")]
    public class UserPreferences : PreferenceActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Create your application here
            this.AddPreferencesFromResource(Resource.Layout.userpreferences);
        }

        protected override void OnResume()
        {
            base.OnResume();

            this.GetPreferences(FileCreationMode.Private).RegisterOnSharedPreferenceChangeListener(this);
        }

        protected override void OnPause()
        {
            base.OnPause();

            this.GetPreferences(FileCreationMode.Private).UnregisterOnSharedPreferenceChangeListener(this);
        }

        public void OnSharedPreferenceChanged(ISharedPreferences prefs, string key)
        {
            // Do something with the changed value pointed to by key
        }
    }
}

もちろん、両方ともRegisterOnSharedPreferenceChangeListenerからにUnregisterOnSharedPreferenceChangeListener変換することはできません。UserPreferencesISharedPreferencesOnSharedPreferenceChangeListener

著者がこれをどのように機能させるつもりだったのかはわかりません。どんな助けでも大歓迎です。

また、サンプル コードをwrox.comからダウンロードしようとしましたが、サンプル コードに環境設定の変更をリッスンする機能が含まれていませんでした。

編集:

次のコードはコンパイルされますOnSharedPreferenceChangedが、設定で更新が行われたときに呼び出されることはありません。

    public class UserPreferences : PreferenceActivity, ISharedPreferencesOnSharedPreferenceChangeListener
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Create your application here
            this.AddPreferencesFromResource(Resource.Layout.userpreferences);
        }

        protected override void OnResume()
        {
            base.OnResume();

            this.GetPreferences(FileCreationMode.Private).RegisterOnSharedPreferenceChangeListener(this);
        }

        protected override void OnPause()
        {
            base.OnPause();

            this.GetPreferences(FileCreationMode.Private).UnregisterOnSharedPreferenceChangeListener(this);
        }

        void ISharedPreferencesOnSharedPreferenceChangeListener.OnSharedPreferenceChanged(ISharedPreferences prefs, string key)
        {
            // Do something with the changed value pointed to by key
        }
    }
4

4 に答える 4

4

I was working through exactly the same example, and had no problem getting the OnPause and OnResume events to fire.

The problem was that registering/unregistering the listener on pause/resume worked, but had absolutely no effect. The listener itself never fired.

Switching to the actual UserPreferences intent caused the OnPause to fire, deregistering the listener. And vice versa, when I came back from it. But that was only part of the problem. I couldn't even get the preferences to load properly using this method

this.GetPreferences(FileCreationMode.Private).RegisterOnSharedPreferenceChangeListener(this);

(I assume the reason was because the activities I was using had different names, the launcher was called PreferencesDemoActivityand the preferences themselves were being handled by UserPreferences - see below).

Unfortunately the solution marked as answer above with

PreferenceScreen.SharedPreferences.RegisterOnSharedPreferenceChangeListener(this);

Doesn't work either (it complains about SharedPreferences not being available in a static context).

Once I moved all the OnPause/OnResume/Listener code to inside the UserPreferences class, it all worked perfectly.

However, that was no good to me. I needed my MAIN app to immediately respond to changes to the preferences, and not have to re-read them all when returning from the preferences screen, and check for changes.

The only way I could get the actual OnSharedPreferenceChanged listener in my 'main' class to fire when something changed in my (separate) preferences screen was to implement it thus:

[Activity(Label = "More user preferences", MainLauncher = true, Icon = "@drawable/icon")]
public class PreferencesDemoActivity : Activity, ISharedPreferencesOnSharedPreferenceChangeListener
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        // Get our button from the layout resource,
        // and attach an event to it
        Button button = FindViewById<Button>(Resource.Id.MyButton);

        // !!!NB !!! Remember to implement ISharedPreferencesOnSharedPreferenceChangeListener in this class, 
        // or you'll never get to OnSharedPreferenceChanged method
        PreferenceManager.GetDefaultSharedPreferences(this).RegisterOnSharedPreferenceChangeListener(this);

        button.Click += delegate
                            {
                                Intent i = new Intent(this, new UserPreferences().Class);
                                this.StartActivityForResult(i, 0); // this ensures that we come back to this one when we exit the pref screen
                            };

    }


    /// <summary>
    /// Remember to implement ISharedPreferencesOnSharedPreferenceChangeListener in this class, or you'll never get this method to compile
    /// </summary>
    /// <param name="sharedPreferences"></param>
    /// <param name="key"></param>
    public void OnSharedPreferenceChanged(ISharedPreferences sharedPreferences, string key)
    {
        Log.Debug("MUP", string.Format("Preference {0} changed", key));

        if (key == "PREF_AUTO_UPDATE")
        {
            bool autoRefresh = sharedPreferences.GetBoolean("PREF_AUTO_UPDATE", false);
            Log.Debug("MUP", string.Format("Preference {0} changed to {1}", key, autoRefresh));
        }

    }

That worked for me, and solved my problem. The key appeared to be to use PreferenceManager.GetDefaultSharedPreferences.

于 2013-01-01T02:54:02.570 に答える
2

使用する必要があります

PreferenceScreen.SharedPreferences.RegisterOnSharedPreferenceChangeListener(this);

それ以外の

 this.GetPreferences(FileCreationMode.Private).RegisterOnSharedPreferenceChangeListener(this);
于 2012-06-24T17:09:41.117 に答える
2

お気づきのように、これらのメソッドに を実装するクラスのインスタンスを与える必要がありますISharedPreferencesOnSharedPreferenceChangeListener。これは別のクラスである可能性があります。または、そのサンプルのように「this」を使用する場合は、クラスを変更してそのインターフェイスを実装します。

[Activity(Label = "User Preferences")]
public class UserPreferences : PreferenceActivity, ISharedPreferencesOnSharedPreferenceChangeListener
{
    // OnCreate, OnResume, etc

    public void OnSharedPreferenceChanged(ISharedPreferences sharedPreferences, string key)
    {
    }
}
于 2012-05-10T18:43:21.033 に答える
0

これは、Samsung Galaxy Nexus で発生した問題の症状である可能性があります。アプリ (古い Android 2.3.4 フォンでは正常に動作していた)をAndriod 4.0.2 フォンにデバッグしたとき、、、、、OnStartまたはイベントはまったくトリガーされませんでした。OnResumeOnPauseOnStop

このような新しい電話で作業している場合は、Mono for Android プロジェクトのプロパティで、サポートされているアーキテクチャとして「armeabi-v7a」を追加してみてください。

サポートのニーズによっては、「armeabi-v7a」アーキテクチャのみを提供できる場合があります。

于 2012-05-25T15:56:15.330 に答える