RecyclerView.Adapter
の違いを得るには、新しいDiffUtil
を試してみます。しかし、リロード上の古いカーソルは、diffが計算される前に閉じられているので、わかりません。これはCursorCallback
はCallback
ベースで、このAdapter
は私のベースであり、ここで私の活動のコードです:DiffUtilコールバックでカーソルを早く閉じた
public class RecyclerActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{
private RecyclerView recyclerView;
private ItemAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter = new ItemAdapter(this));
recyclerView.setItemAnimator(new ItemAnimator());
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
long id = recyclerView.getAdapter().getItemId(viewHolder.getAdapterPosition());
viewHolder.itemView.getContext().getContentResolver().delete(ContentUris.withAppendedId(CategoryContract.CONTENT_URI, id), null, null);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
getSupportLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(this, CategoryContract.CONTENT_URI, CategoryContract.PROJECTION, null, null, CategoryContract.COLUMN_ID + " DESC");
}
public void addItem(View button) {
int count = recyclerView != null ? recyclerView.getChildCount() : 0;
ContentValues v = new ContentValues(1);
v.put(CategoryContract.COLUMN_NAME, "Foo Nr. " + count);
getContentResolver().insert(CategoryContract.CONTENT_URI, v);
}
private Task setter;
@Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) {
if(setter != null) {
setter.cancel(true);
}
setter = new Task(adapter);
AsyncTaskCompat.executeParallel(setter, adapter.getCursor(), data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.changeCursor(null);
}
public static class Task extends AsyncTask<Cursor, Void, Pair<Cursor, DiffUtil.DiffResult>> {
private final CursorRecyclerViewAdapter adapter;
Task(CursorRecyclerViewAdapter adapter) {
this.adapter = adapter;
}
@Override
protected Pair<Cursor, DiffUtil.DiffResult> doInBackground(Cursor... params) {
return Pair.create(params[1], DiffUtil.calculateDiff(new ItemCallback(params[0], params[1])));
}
@Override
protected void onPostExecute(Pair<Cursor, DiffUtil.DiffResult> diffResult) {
if(isCancelled())
return;
adapter.swapCursor(diffResult.first);
diffResult.second.dispatchUpdatesTo(adapter);
}
}
public static class ItemAdapter extends CursorRecyclerViewAdapter<ItemHolder>
{
ItemAdapter(Context context) {
super(context, null);
}
@Override
public void onBindViewHolder(ItemHolder viewHolder, Cursor cursor) {
CategoryModel model = CategoryModel.FACTORY.createFromCursor(cursor);
viewHolder.textView.setText(model.getId() + " - " + model.getName());
}
@Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ItemHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false));
}
}
public static class ItemHolder extends RecyclerView.ViewHolder {
TextView textView;
ItemHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.textView);
}
}
public static class ItemCallback extends CursorCallback<Cursor> {
public ItemCallback(Cursor newCursor, Cursor oldCursor) {
super(newCursor, oldCursor);
}
@Override
public boolean areRowContentsTheSame(Cursor oldCursor, Cursor newCursor) {
CategoryModel oldCategory = CategoryModel.FACTORY.createFromCursor(oldCursor);
CategoryModel newCategory = CategoryModel.FACTORY.createFromCursor(newCursor);
return oldCategory.getName().equals(newCategory.getName());
}
@Override
public boolean areCursorRowsTheSame(Cursor oldCursor, Cursor newCursor) {
return oldCursor.getLong(0) == newCursor.getLong(0);
}
}
}
すべてのヘルプは大歓迎です。おそらく古いカーソルは、同じクエリを持つ新しいカーソルが返されたときに閉じられます。カーソルはgetCursor()
をonLoadFinished()
に呼び出した時点で開かれていますが、最初の使用時にはCursorCallback
で閉じられます。
@ρяσѕρєяK:問題はまだ存在します。読みやすさのための変更だけです。 – Happo
@Happo:Ok、user1643723答えはいいと思います。 –
DiffUtilはリストのどの部分にも即座にランダムアクセスする必要があるのに対し、これらのカーソルの目的はデータベースから遅延データをロードすることであるため、ウィンドウカーソル(SQLiteCursorなど)でDiffUtilを使用することは非常に悪い考えです。すべてを最初に完全にメモリにロードする必要があります。 CursorがSQLiteCursorの場合、カーソルデータ全体をリストに最初に転送するか、DiffUtilを使用しないでください。 – BladeCoder