DBからデータを取得しているListViewがあります。各行をクリックすると、次のように右と後ろにアニメーション化されます。
@Override
public void onItemClick(AdapterView<?> av, View v, int pos, long id) {
...
pos = pos - mList.getFirstVisiblePosition();
mList.getChildAt(pos).startAnimation(anim );
...}
アニメーションは約 1 秒続きます。右にスライドしてから後ろにスライドします。
アニメーション中に DB とのやり取りがなければ、この部分は正常に動作します
これで、リストの各アイテムが DB にカウンターを持ちます。ユーザーがリストからアイテムをクリックするたびに、DB でカウンターが増加する必要があり、アイテムごとに ListView にも視覚的に表示されます。
したがって、DB は ContentProvider を介して表示されます
これが問題です:
アイテムをクリックするたびにアニメーションが開始され、ContentResolver を介して DB に対して更新が実行されます。問題は、アニメーションが適切な要素で開始されますが、開始直後に突然停止し、リストの他の要素で終了することです。
リストに4つの要素がある場合
----------1----------
----------2----------
----------3----------
----------4----------
要素1をクリックすると、番号1が右にスライドし始めますが、約200ミリ秒後に停止し、要素4はアニメーションの残りの部分で停止した場所からアニメーションを続けます
2を押しても同じことが再現できますが、今回は3でアニメーションが終了します。3 の場合は 2 で終了します。4 をクリックすると 1 になります。
表示されている項目が 4 つだけであると仮定すると、リスト全体で再現できます。
それは常に反対の要素です。onItemClick で位置をデバッグしますが、常に正しいです。
重要 DB で更新を行うコードをコメント アウトすると、すべて正常に動作します。これは、アニメーション中に DB から LoaderManager を介して ListView の SimpleCursorAdapter が新しい Cursor で更新されるときに問題が発生することを示唆しています。
ContentProvider の代わりに CommonsWare Loaderex を使用してみたこと。同じ効果が得られます。
コードスニペット
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
return new CursorLoader(this.getActivity(), MyContentProvider.CONTENT_URI,
new String[]{}, "uid>0 AND distance<80000", null, "distance LIMIT 100");
}
public void onLoadFinished(Loader<Cursor> ld, Cursor c) {
merchantAdapter.swapCursor(c);
}
OnItemClick には次のコードがあります。
ContentResolver cr = getActivity().getContentResolver();
ContentValues cv = new ContentValues();
cv.put("counter", counter);
Uri mUri = ContentUris.withAppendedId(MyContentProvider.CONTENT_URI, uid);
cr.update(mUri, cv, null, null);
また、上記の cr.update(...
更新のたびにリストを更新するためにこれを行います
getActivity()).lm.getLoader(0).forceLoad();
アニメーションの問題は Android のバグでしょうか? または私が欠けているものは何ですか?
これを解決するための現在のアイデア は、アニメーションの期間中クリックをブロックし、アニメーションの期間が経過した後にハンドラーで cr.update を作成して、リフレッシュがアニメーションに影響を与えないようにすることだと思います。
お知らせ下さい