10

Honeycomb では、バックグラウンド スレッドで面倒な作業を行うことでアプリケーションにデータを提供する適切な方法として、ローダーAPI が導入されました。私のアプリケーションでは、すべてのCursors をLoaders を返すCursors に置き換える作業を行っています。は現在減価償却されているため、 を呼び出してバックグラウンド スレッドで作業を再度実行できるようにし、それが に戻ったときに実行するCursor.requery()ことをお勧めします。restartLoaderchangeCursoronLoadFinished

Cursor.requery()これはすべて、更新されたデータを持つ同じ Cursor インスタンスであったため、これを使用してデータを再クエリしたいときに ListView がスクロール位置を維持しないことを除いて、うまく機能します。

スクロール位置を失わずにローダーを更新するにはどうすればよいですか?

4

2 に答える 2

6

Loaderクラス自体は、データセットがいつ変更されるかを認識せず、現在に固有の実装ですCursorLoader。アプリケーション内で更新する必要のあるデータはローカルSQLiteデータベース(ContentProviderなし)内にあるためCursorLoader、Dianne Hackborneが開発者グループで述べたように、代わりにローカルデータベースを使用するようにを変更する必要がありました。

残念ながら、loadInBackgroundからカーソルを返すだけではContentObserver、データが変更されたときにローダーに適切に通知できません。これは、カーソルでが呼び出されたときにAbstractCursorのみ呼び出すためです。notifyChanged()requery()

ContentObserverデータが変更されたことを通知することは決してないので、必要に応じて自分自身にLoader電話をかけるLoader.onContentChanged()ことになりました。この時点では、すべてが機能しているように見えますが、重大な問題が発生した場合は、この回答を更新します。

于 2011-08-28T08:12:21.347 に答える
1

ローダーのロードごとに新しいアダプターを作成しないでください。つまり..

@Override
    public void onLoadFinished(Loader<List<NotificationItem>> loader, List<NotificationItem> notifications) {
        // We must do it in this way to not losing listview scroll position after a reload.
        if(mAdapter==null) {
            mAdapter = new HomeUserActivityListAdapter(getActivity(), notifications);
            mListView.setAdapter(mAdapter);

        }else{
            mAdapter.refill(notifications);
        }
    }

そして、アダプターでアイテムを補充するメソッドを作成します

public void refill(List<NotificationItem> notifications) {
    mNotificationsList.clear();
    mNotificationsList.addAll(notifications);
    notifyDataSetChanged();
}

以上で、スクロール位置が正確に維持されます:-)

于 2015-02-16T10:21:36.570 に答える