删除项目后,RecyclerView不会更新

时间:2018-04-15 18:22:34

标签: android android-recyclerview realm recycler-adapter

我正在实施RecyclerView以显示交易列表。在其两个ViewHolders之一中,有一个删除事务的按钮。问题是,点击按钮后,RecyclerView没有任何反应。我正在使用Realm和MVP模式,并尝试了我能找到的所有解决方案,但似乎没有任何效果。

这是TransactionListActivity,其中将显示RecyclerView:

public class TransactionListActivity extends BaseActivity implements TransactionListView {

private static final String TAG = "TransactionListActivity";

@Inject
TransactionListPresenterInterface<TransactionListView> mPresenter;

TransactionListAdapter transactionListAdapter;

@BindView(R.id.transaction_list_recyclerview)
RecyclerView transactionListRecyclerView;

@Override
public void onPrepareTransactionListAdapter() {
    LinearLayoutManager layoutManager
            = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);

    transactionListRecyclerView.setLayoutManager(layoutManager);

    List<TransactionListItem> transactionListItems = mPresenter.getAllTransactionItems();

    transactionListAdapter = new TransactionListAdapter(this, transactionListItems);
    transactionListAdapter.setOnDeleteTransactionClickListener(this::onDeleteTransaction);

    transactionListRecyclerView.setAdapter(transactionListAdapter);

}

@Override
public void onDeleteTransaction(String id) {
    mPresenter.onDeleteTransactionClick(String id);
}

@Override
public void refresh() {
    transactionListAdapter.notifyDataSetChanged();
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_transaction_list);

    getActivityComponent().inject(this);

    setUnBinder(ButterKnife.bind(this));
    ButterKnife.bind(this);

    mPresenter.onAttach(this);

    onPrepareTransactionListAdapter();
}

这是我的适配器:

public class TransactionListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private static final String TAG = "TransactionListAdapter";

private Context context;
public List<TransactionListItem> transactionListItems;
private OnDeleteTransactionClickListener mOnDeleteTransactionClickListener;

public TransactionListAdapter(Context context, List<TransactionListItem> transactionListItems) {
    this.context = context;
    this.transactionListItems = transactionListItems;
}

class TransactionItemViewHolder extends RecyclerView.ViewHolder {

    ...

    @BindView(R.id.delete_transaction_button)
    Button deleteTransactionButton;

    ...

    public TransactionItemViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }
}

class TransactionDateViewHolder extends RecyclerView.ViewHolder {
    ...
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    RecyclerView.ViewHolder viewHolder = null;
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());

    switch(viewType) {

        case TransactionListItem.TYPE_DATE:
            //inflate TransactionDateViewHolder here

        case TransactionListItem.TYPE_TRANSACTION:
            //inflate TransactionItemViewHolder here
    }

    return viewHolder;
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {

    switch(viewHolder.getItemViewType()) {

        case TransactionListItem.TYPE_TRANSACTION:

            ProductStockRecord productStockRecord = (ProductStockRecord) transactionListItems.get(position);
            TransactionItemViewHolder transactionItemViewHolder = (TransactionItemViewHolder) viewHolder;
            // populate view with data here
            ((TransactionItemViewHolder) viewHolder).deleteTransactionButton.setOnClickListener(v -> {
                if (mOnDeleteTransactionClickListener != null) {
                    mOnDeleteTransactionClickListener.onDeleteTransactionClick(productStockRecord.getId());
                }
            });
            break;

        case TransactionListItem.TYPE_DATE:

            //populate view with data here
            break;

    }

}

@Override
public int getItemCount() {
    return transactionListItems.size();
}

@Override
public int getItemViewType(int position) { return transactionListItems.get(position).getType(); }

public void setOnDeleteTransactionClickListener(final OnDeleteTransactionClickListener onDeleteTransactionClickListener) {
    mOnDeleteTransactionClickListener = onDeleteTransactionClickListener;
}

public interface OnDeleteTransactionClickListener {
    void onDeleteTransactionClick(String id);
}

}

这是我的主持人:

public class TransactionListPresenter<V extends TransactionListView> extends BasePresenter<V> implements TransactionListPresenterInterface<V>, RealmDataManager.OnTransactionCallback {

private static final String TAG = "TransaxListPresenter";

@Inject
public TransactionListPresenter(final RealmDataManager realmDataManager) { super(realmDataManager); }

@Override
public List<TransactionListItem> getAllTransactionItems() {
    List<ProductStockRecord> productStockRecordList = getRealmDataManager().getAllProductStockRecords();

    List<TransactionListItem> transactionListItems = new ArrayList<>();
    // preprocess transactions here

    return transactionListItems;
}

@Override
public void onDeleteTransactionClick(String id) {
    getRealmDataManager().deleteProductStockRecord(id, this);
    getView().refresh();
    Log.d(TAG,"deleteTransaction() performed");
}

}

这是RealmService的更新(和工作)版本,上面的所有代码都已相应修复:

public void deleteProductStockRecord(final String id, final OnTransactionCallback onTransactionCallback) {
    mRealm.executeTransactionAsync(realm -> {
        ProductStockRecord productStockRecord = realm.where(ProductStockRecord.class).equalTo("id", id).findFirst();
        productStockRecord.deleteFromRealm();
    }, () -> {
        if (onTransactionCallback != null) {
            onTransactionCallback.onRealmSuccess();
        }
    }, error -> {
        if (onTransactionCallback != null) {
            onTransactionCallback.onRealmError(error);
        }
    });
}

我相信我在适配器实现中的某些地方犯了一些错误。如果有人能帮我解决问题,指出我的错误,或者指出我正确的方向,我会非常感激。提前致谢

2 个答案:

答案 0 :(得分:0)

我认为问题可能在于您的适配器中未更新对List<TransactionListItem>的引用。

如果您在演示者中查看此代码,则:

@Override
public List<TransactionListItem> getAllTransactionItems() {
    List<ProductStockRecord> productStockRecordList = getRealmDataManager().getAllProductStockRecords();

    List<TransactionListItem> transactionListItems = new ArrayList<>();
    // preprocess transactions here

    return transactionListItems;
}

您正在创建一个新的List<TransactionListItem>,它是适配器所指向的。因此,在您的onDeleteTransactionClick方法中,必须确保在调用getView().refresh()之前将更新的列表传递给适配器。因为否则,适配器中的列表将不会更改,并且您会看到该项目没有被删除。

但是理想情况下,我建议使用类似DiffUtil(或手动计算)的方法来获取已删除项目的位置并调用notifyItemRemoved,而不是刷新整个RecyclerView

答案 1 :(得分:0)

如果您的意思是“ recyclerview显然没有改变”:

如果您从回收站视图中删除项目,则可以使用mAdapter.notifyDataSetChanged();。这样做会在调用时将可见的recyclerview的内容更新为适配器列表中的项目。

相关问题