我在我的活动中使用游标加载器在用户的商店中加载产品并使用游标在Recycler视图中显示它。 Recycler视图有多种视图类型(三种是特定的)。用户可以删除产品。当用户删除产品时,我在sqlite中设置了一个标志,并且游标加载器通知我有关更改的信息。但是,我无法相应地更改Recycler View中的可视化。我尝试交换光标并使用'notifyDataSetChanged()'但它没有任何效果,即视图没有刷新。我明白,要使动画工作,我应该删除一个项目并使用notifyItemDeletedAt(position)通知适配器,但是如何使用游标加载器实现这一点,我得到的唯一回调是新游标?我现在找到的唯一解决方案是在单击删除时编写自定义动画,然后在收到'onLoadFinished()'回调并使其滚动到最后一个适配器的位置时初始化新适配器。但它会导致紧张不安的效果。
我发布了下面的RecylerView适配器片段。如何使用游标和游标加载器在回收器视图中实现流畅的动画和视图刷新,而无需初始化新的适配器并使用notifyItemDeletedAt()函数。
private static final int TYPE_SHOPPERTS_PRODUCT = 1;
private static final int TYPE_SELF_PRODUCT = 2;
private static final int TYPE_SELF_COLLECTION = 3;
public AgentStoreProductsInCategoryAdapter(Activity iActivity, Cursor iProductsCursor) {
this.productsCursor = iProductsCursor;
this.mActivity = iActivity;
this.agentId = SystemPreferenceManager.getAgentId(iActivity.getApplicationContext());
}
// This code did not work for me
public void swapCursor(Cursor iNewCursor){
this.productsCursor = iNewCursor;
this.notifyDataSetChanged();
}
// root view holder - the three child view holders extend from this
public class ProductPreviewViewHolder extends RecyclerView.ViewHolder{
View view;
ImageView deleteProductButton;
// MORE DECLERATIONS
public ProductPreviewViewHolder(View iView){
super(iView);
this.view = iView;
deleteProductButton = (ImageView)view.findViewById(R.id.delete_button);
}
}
public class ShoppertsProductPreviewViewHolder extends ProductPreviewViewHolder {
DeleteProductListener deleteProductListener = new DeleteProductListener();
// MORE DECLERATIONS
public ShoppertsProductPreviewViewHolder(View iView) {
super(iView);
deleteProductButton.setOnClickListener(deleteProductListener);
// MORE INITIALIZATIONS
}
}
public class SelfProductPreviewViewHolder extends ProductPreviewViewHolder {
DeleteProductListener deleteProductListener = new DeleteProductListener();
// MORE DECLERATIONS
public SelfProductPreviewViewHolder(View view) {
super(view);
deleteProductButton.setOnClickListener(deleteProductListener);
// MORE INITIALIZATIONS
}
}
public class CollectionPreviewViewHolder extends ProductPreviewViewHolder {
DeleteCollectionListener deleteCollectionListener = new DeleteCollectionListener();
public CollectionPreviewViewHolder(View view) {
super(view);
deleteProductButton.setOnClickListener(deleteCollectionListener);
// MORE INITIALIZATIONS
}
}
@Override
public ProductPreviewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
switch (viewType){
case TYPE_SHOPPERTS_PRODUCT:
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_product_agent_store_shopperts, parent, false);
return new ShoppertsProductPreviewViewHolder(itemView);
case TYPE_SELF_PRODUCT:
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_product_agent_store_self, parent, false);
return new SelfProductPreviewViewHolder(itemView);
case TYPE_SELF_COLLECTION:
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_collection_agent_store, parent, false);
return new CollectionPreviewViewHolder(itemView);
default:
return null;
}
}
@Override
public int getItemViewType(int position) {
productsCursor.moveToPosition(position);
final int numProducts;
if (productsCursor.getColumnIndex(
ViewContract.AgentStoreCollectionView.COLUMN_NUM_PRODUCTS) != -1) {
numProducts = productsCursor.getInt(productsCursor.getColumnIndex(
ViewContract.AgentStoreCollectionView.COLUMN_NUM_PRODUCTS));
} else {
numProducts = 1;
}
int productSource = productsCursor.getInt(productsCursor.getColumnIndex(
AgentStoreContract.AgentStoreEntry.COLUMN_PRODUCT_SOURCE));
if (productSource != agentId){
return TYPE_SHOPPERTS_PRODUCT;
} else {
if (numProducts == 1) {
return TYPE_SELF_PRODUCT;
} else {
return TYPE_SELF_COLLECTION;
}
}
}
@Override
public long getItemId(int position){
productsCursor.moveToPosition(position);
return productsCursor.getInt(productsCursor.getColumnIndex
(AgentStoreContract.AgentStoreEntry._ID));
}
@Override
public void onBindViewHolder(final ProductPreviewViewHolder holder, int position) {
productsCursor.moveToPosition(position);
final int productId = productsCursor.getInt(productsCursor.getColumnIndex(
AgentStoreContract.AgentStoreEntry.COLUMN_PRODUCT_ID));
if (holder instanceof ShoppertsProductPreviewViewHolder) {
ShoppertsProductPreviewViewHolder shoppertsProductPreviewViewHolder =
(ShoppertsProductPreviewViewHolder) holder;
shoppertsProductPreviewViewHolder.deleteProductListener.updateData(productId,
holder.view);
// SOME MORE CODE
} else if (holder instanceof SelfProductPreviewViewHolder) {
SelfProductPreviewViewHolder selfProductPreviewViewHolder =
(SelfProductPreviewViewHolder) holder;
selfProductPreviewViewHolder.deleteProductListener.updateData(productId,
holder.view);
// SOME MORE CODE
} else if (holder instanceof CollectionPreviewViewHolder){
final CollectionPreviewViewHolder collectionPreviewViewHolder =
(CollectionPreviewViewHolder) holder;
collectionPreviewViewHolder.deleteCollectionListener.updateData(collectionId,
holder.view);
// SOME MORE CODE
}
}
@Override
public int getItemCount() {
if (productsCursor != null) {
return productsCursor.getCount();
} else{
return 0;
}
}
// Custom code for slide_right when delete button is clicked and to update the database accordingly for deleting a collection
protected void removeCollection(final Context context, final View rowView, final int collectionId) {
final Animation animation = AnimationUtils.loadAnimation(
context, android.R.anim.slide_out_right);
animation.setAnimationListener(new Animation.AnimationListener() {
public void onAnimationEnd(Animation anim) {
rowView.clearAnimation(); // to get rid of flicker at end of animation
rowView.setVisibility(View.GONE);
ContentValues storeEntry = new ContentValues();
storeEntry.put(AgentStoreContract.AgentStoreEntry.COLUMN_DELETED,
Constants.DeletedStatus.DELETED);
String where = AgentStoreContract.AgentStoreEntry.COLUMN_COLLECTION_ID + "=?";
String args[] = new String[]{Integer.toString(collectionId)};
context.getContentResolver().update(AgentStoreContract.AgentStoreEntry.CONTENT_URI,
storeEntry, where, args);
SyncStoreIntentService.startActionSyncEntireStore(context);
}
public void onAnimationRepeat(Animation arg0) {}
public void onAnimationStart(Animation arg0) {
}
});
rowView.startAnimation(animation);
}
// Custom code for slide_right when delete button is clicked and to update the database accordingly
protected void removeListItem(final Context context, final View rowView, final int productId) {
final Animation animation = AnimationUtils.loadAnimation(
context, android.R.anim.slide_out_right);
animation.setAnimationListener(new Animation.AnimationListener() {
public void onAnimationEnd(Animation anim) {
rowView.clearAnimation(); // to get rid of flicker at end of animation
rowView.setVisibility(View.GONE);
ContentValues storeEntry = new ContentValues();
storeEntry.put(AgentStoreContract.AgentStoreEntry.COLUMN_DELETED,
Constants.DeletedStatus.DELETED);
String where = AgentStoreContract.AgentStoreEntry.COLUMN_PRODUCT_ID + "=?";
String args[] = new String[]{Integer.toString(productId)};
context.getContentResolver().update(AgentStoreContract.AgentStoreEntry.CONTENT_URI,
storeEntry, where, args);
SyncStoreIntentService.startActionSyncEntireStore(context);
}
public void onAnimationRepeat(Animation arg0) {}
public void onAnimationStart(Animation arg0) {
}
});
rowView.startAnimation(animation);
}
// Listener for deleting a product
private class DeleteProductListener implements View.OnClickListener{
int productId;
View view;
public void updateData(int iProductId, View iView){
this.productId = iProductId;
this.view = iView;
}
@Override
public void onClick(View v) {
if (view != null) {
removeListItem(v.getContext(), view, productId);
}
}
}
// Listener for deleting a collection
private class DeleteCollectionListener implements View.OnClickListener{
int collectionId;
View view;
public void updateData(int iCollectionId, View iView){
this.collectionId = iCollectionId;
this.view = iView;
}
@Override
public void onClick(View v) {
if (view != null) {
removeCollection(v.getContext(), view, collectionId);
}
}
}
这是onLoadFinished()函数
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
switch(loader.getId()) {
case LOADER_PRODUCTS:
int mScrollPosition = 0;
if (layoutManager != null) {
mScrollPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
}
productsAdapter = new AgentStoreProductsInCategoryAdapter(
AgentStoreProductsInCollectionActivity.this,
data);
productsRecyclerView.setAdapter(productsAdapter);
productsRecyclerView.invalidate();
mScrollPosition = mScrollPosition <= data.getCount() ? mScrollPosition : data.getCount();
layoutManager.scrollToPosition(mScrollPosition);
}
}