android - RecyclerView.Adapter onBindViewHolder() 位置错误

标签 android android-recyclerview android-adapter

我会展示代码和解决问题的步骤。

我在一个选项卡式 fragment 中有一个 recyclerview,它从自定义对象中获取数据集:

mRecyclerView = (RecyclerView) v.findViewById(R.id.recyclerview);

mRecyclerView.setLayoutManager(mLayoutManager);

mRecyclerAdapter = new MyRecyclerAdapter(mMes.getListaItens(), this, getActivity());

mRecyclerView.setAdapter(mRecyclerAdapter);

我在适配器的 onBindViewHolder() 中设置列​​表项的长按行为:

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {

    ItemMes item = mListaItens.get((position));

    holder.descricao.setText(item.getDescrição());
    holder.valor.setText(MainActivity.decimalFormatWithCod.format(item.getValor()));

    ...

    holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {

            new MaterialDialog.Builder(mContext)
                    .title(holder.descricao.getText().toString())
                    .items(R.array.opcoes_longclick_item)
                    .itemsCallbackSingleChoice(-1, new MaterialDialog.ListCallbackSingleChoice() {
                        @Override
                        public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {

                            switch (which) {
                                case 0:
                                    mParentFragment.showUpdateItemDialog(position);
                                    return true;

                                case 1:
                                    mParentFragment.showDeleteItemDialog(position);
                                    return true;
                            }

                            return false;
                        }
                    })
                    .show();

            return true;
        }
    });

}

然后, fragment 中负责删除项目本身的方法:

public void showDeleteItemDialog(int position) {

    final ItemMes item = mMes.getListaItens().get(position);

    new MaterialDialog.Builder(getActivity())
            .title("Confirmar Remoção")
            .content("Tem certeza que deseja remover " + item.getDescrição() + "?")
            .positiveText("Sim")
            .negativeText("Cancelar")
            .onPositive(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    deleteItem(item);
                }
            })
            .show();

}

public void deleteItem(ItemMes item) {

    getMainActivity().deleteItemFromDatabase(item.getID());

    int position = mMes.getListaItens().indexOf(item);

    mMes.getListaItens().remove(position);

    mRecyclerAdapter.notifyItemRemoved(position);

    atualizaFragment();

}

最后是 Activity 中执行数据库操作的方法:

 public int deleteItemFromDatabase(long id) {

    SQLiteDatabase db = dataBaseHelper.getWritableDatabase();

    String where = DBHelper.COLUNA_ID + " = ?";

    String[] args = {String.valueOf(id)};

    int rowsAffected = db.delete(DBHelper.TABELA_ITEM, where, args);

    db.close();

    return rowsAffected;

}

现在我将重现这些步骤: 我在 ListView 中显示 3 个项目。然后我尝试删除第一个:

1 - longclick 被拦截传递正确的索引: enter image description here

2 - 该项目已从数据库中正确删除: enter image description here

3 - 在所有这一切之后,正如预期的那样,适配器正在存储和显示 2 个项目... enter image description here

所以,如果我尝试删除这 2 项列表的第一项,我会得到错误的位置(应该是 0,是 1): The position = 1

而且如果我尝试删除这个 2 项列表的最后一项,我会得到错误的位置(应该是 1,是 2): enter image description here

问题是:如果我有一个大小为 2 的数据集(并且适配器知道它),它如何调用 onBindViewHolder(ViewHolder holder, int [last index +1])enter image description here

我不知道哪里出了问题。所以我寻求帮助,因为我正在考虑放弃这个项目,因为我做的每件事都是正确的,但总是有些事情不起作用,而且我很累。 提前致谢。

最佳答案

我注意到在 onBindViewHolder(VH holder, int position) 方法中位置出错时,holder.getAdapterPosition() 总是给我正确的位置。

所以我改变了我的代码:

ItemMes item = mListaItens.get((position));

...

mParentFragment.showUpdateItemDialog(position);

...

mParentFragment.showDeleteItemDialog(position);

....

收件人:

 ItemMes item = mListaItens.get((holder.getAdapterPosition()));

...

mParentFragment.showUpdateItemDialog(holder.getAdapterPosition());

...

mParentFragment.showDeleteItemDialog(holder.getAdapterPosition());

....

一切正常。这很奇怪但是...... 谢谢大家。

关于android - RecyclerView.Adapter onBindViewHolder() 位置错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36986087/

相关文章:

java - 如何确定在 recyclerview 布局上单击了哪个卡片 View ?

java - 将参数从 Activity 传递到另一个 Activity Fragments

android - 当 fragment 在 FragmentPagerAdapter 中完全初始化时等待事件以使用数据设置它们

java - 如果MutableLiveData正在更改,为什么我的ViewModel不调用.observe()并通知适配器?

android - Recyclerview onBindViewHolder 在具有权重的 LinearLayout 内调用所有项目

java - 难以从其他 Activity/类(class)控制 webview

Android SDK 2.3.3 中 7 英寸平板电脑的 Android 虚拟设备配置

android - R 无法解析为变量

android - Button数组的RecyclerView - 如何更新数据?

java - 项目单击监听器不适用于自动滚动回收器 View