从recyclerview中删除项目(viewholder具有onClick但适配器具有数据集)

时间:2018-02-28 19:49:10

标签: android android-recyclerview recycler-adapter android-viewholder

我想在按下项目中的视图时从Recyclerview中删除项目。

情况:使用带有数据集的RecyclerView和ViewHolder创建一个列表,其中有一个onClick用于从列表中删除项目的视图,我需要知道哪个项目已被点击在ViewHolder上并将其与适配器通信,因为适配器具有数据集。在ViewHolder中,我可以知道使用此方法按下了哪个项目:getAdapterPosition(),因此似乎很容易知道要删除的项目。

问题: ViewHolderRecyclerView.Adapter中的子类,而适配器有数据集,所以我试图了解哪种方法最适合viewholder to comunicate必须删除已单击的Item的适配器。

最新技术:我可以在stackoverflow中看到一些问题,其中一些是旧的,其中一些更新,例如:Android RecyclerView addition & removal of items但是解决方案没有阐明如何通信必须删除项目的适配器。用户可能正在使用静态字段或其他东西,但它不是实现这一目标的好方法。我无法看到其他问题中解释的其他方式。

这是来自官方Recyler指南的示例,您可以在其中看到ViewHolder嵌套在适配器内且无法访问它:https://developer.android.com/guide/topics/ui/layout/recyclerview.html

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private String[] mDataset;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView mTextView;
        public ViewHolder(TextView v) {
            super(v);
            mTextView = v;
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        TextView v = (TextView) LayoutInflater.from(parent.getContext())
                .inflate(R.layout.my_text_view, parent, false);
        ...
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.mTextView.setText(mDataset[position]);

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我喜欢RecyclerView example by BigNerdRanch,因为他们有一个自定义ViewHolder,其中包含一个方法(示例中为bindCrime()),该方法是从onBindViewHolder()调用的。此方法从数据列表中获取项目,并根据项目的内容设置所有View

您可以使用类似的方法,让我们称之为bindData(),并且不仅传入数据列表中的项目,还传递自定义回调的[匿名实例],我们称之为ViewHolderCallback ,实际上只是一些界面:

interface ViewHolderCallback{
    void itemWasClicked(int position);
}

然后onBindViewHolder()看起来像这样:

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element
    holder.bindData(mDataset[position], new ViewHolderCallback(){

        @Override
        public void itemWasClicked(int position){
             // remove the item 
        }
    });
}

...和bindData()是这样的:

void bindData(String text, ViewHolderCallback callback){
    mTextView.setText(text);
    itemView.setOnClickListener(new View.OnClickListener(){

        @Override
        public void onClick(View view){
             callback.itemWasClicked(getAdapterPosition()); 
        }
    });
}

答案 1 :(得分:0)

最后我通过更简单的方式解决了这个问题,我刚刚添加了监听器来删除适配器的onBindViewHolder方法中的项目:

PATH_TO_TEST_IMAGES_DIR = 'test_images'
TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpeg'.format(i)) for i in range(5, 7) ]

像魅力一样工作