1

私は私の奇妙な/ユニークな状況を持っていListViewます。これがシナリオです:

MVPデザインパターンを利用しています。開始時に、ActivityWebサービスからデータをフェッチするようにプレゼンターに通知するイベントを発生させます。Webサービス呼び出しは非同期呼び出しです。Webサービスイベントが発生したら、結果を取得して、 /Completed内にあるプロパティ(配列型)にプッシュします。ViewActivity

私が言及したことはすべてうまく機能します、デバイスが回転するとすぐに、いくつかの興味深い開発が行われます。

非同期呼び出しは通常どおり再開され、プロパティ(Array)に値を提供します。したがって、そこには何も問題はありません...(そして、コレクションにデータがあります)次に、を設定しListView Adapterて呼び出しますがnotifyDataSetChanged、何も起こりません。UIが更新されていないか?? 再入力するとActivity、データが再び表示されますか?

私も電話invalidateViewsをかけてみinvalidateましたListView-これは何もしませんでした。

誰かがこの問題で私を助けてくれませんか?よろしくお願いします!

[アップデート]

私はJavaではなくC#(Xamarin)を使用しているという事実を強調したいと思います(:sigh:-はい、わかっています)。さらに、私はASyncTaskクラスを利用していません。代わりに、VisualStudioによって生成されたプロキシクラス内で作成された非同期メソッドを利用しています。非常に簡単ですが、これはデータを入力するコードですListView-プロパティはプレゼンターから設定されます

プレゼンター

ビューのタイプがIContactsViewの場合

    protected override void OnCollectData(System.Collections.IEnumerable data, Type typeOfData)
    {
        if (data != null && typeOfData != null && typeOfData.Equals(typeof(UserContact)))
        {
            this.View.UserInformationCollection = data.Cast<UserContact>().ToArray();
        }
    }

アクティビティ

アクティビティはIContactsViewを実装します

    public UserContact[] UserInformationCollection
    {
        get
        {
            return this._userInformationCollection;
        }
        set 
        {
            this.RunOnUiThread(() =>
                {
                    this._userInformationCollection = value;                        
                    ListView listview = this.FindViewById<ListView>(Resource.Id.userLV);
                    if (listview != null)
                    {                           
                        UserContact[] subsidiesList = this.GetIndexedContacts(this._userInformationCollection);
                        listview.Adapter = new ContactsAdapter(this, subsidiesList.ToList());
                        ((ContactsAdapter)listview.Adapter).NotifyDataSetChanged();
                    }
                });
        }
    }

[/アップデート]

4

2 に答える 2

2

はるかに優れた解決策を見つけました!だから、そのstatic variable考えを無視してください!

アクティビティ:

をオーバーライドしてOnRetainNonConfigurationInstance、プレゼンターを返します

    public override Java.Lang.Object OnRetainNonConfigurationInstance()
    {
        return this._presenter;
    }

OnCreateチェック内でLastNonConfigurationInstance、プレゼンターを取得します-nullでない場合:

    protected override void OnCreate(Bundle bundle)
    {
        ...
        if (this.LastNonConfigurationInstance != null)
        {
            this._presenter = this.LastNonConfigurationInstance as ContactsPresenter;
            this._presenter.RefreshView(this);
        }
        else
        {
            // create a new presenter
            this._presenter = new ContactsPresenter(this);
        }
        ...
    }

それで、多分、あなたは私が前のコードサンプルでしたことを見ましたか?はい、アクティビティの新しいインスタンスをプレゼンターに送信します-を見てくださいRefreshView

プレゼンター:

したがって、ベースプレゼンター内では、次の方法があります。

public class Presenter<T> : Java.Lang.Object, IPresenter where T : IView
{
    /// <param name="view">The view.</param>
    public void RefreshView(T view)
    {
        this.View = view;
    }
}

上記のコードは、プレゼンターが新しいアクティビティの作成について言うのに役立ちます。したがって、非同期呼び出しの後にデータを返すと、アクティビティの最新かつ最大のインスタンスが含まれます。

お役に立てれば!敬具、

于 2012-11-23T07:21:22.070 に答える
1

次のようにして動作させました。

アクティビティの静的変数を宣言します。

    private static ContactsActivity _cachedActivity = null;

アクティビティOnResume内をオーバーライドし、変数を設定します。

    protected override void OnResume()
    {
        base.OnResume();
        _cachedActivity = this;
    }

OnCreateアクティビティ内をオーバーライドし、変数を設定します。

    protected override void OnCreate(Bundle bundle)
    {
        ...
        _cachedActivity = this;
        ...
    }

最後に、前述のプロパティを変更しました。

    public USBUserContact[] UserInformationCollection
    {
        get
        {
            return this._userInformationCollection;
        }
        set
        {
            _cachedActivity.RunOnUiThread(() =>
                {
                    _cachedActivity._userInformationCollection = value;
                    ListView listview = _cachedActivity.FindViewById<ListView>(Resource.Id.userLV);
                    if (listview != null)
                    {
                        UserContact[] subsidiesList = _cachedActivity.GetIndexedContacts(_cachedActivity._userInformationCollection);
                        listview.Adapter = new ContactsAdapter(_cachedActivity, subsidiesList.ToList());
                        ((ContactsAdapter)listview.Adapter).NotifyDataSetChanged();
                    }
                });
        }
    }

敬具、

于 2012-11-22T11:23:47.230 に答える