Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何从RecyclerView适配器返回数据?_Android_Android Recyclerview - Fatal编程技术网

Android 如何从RecyclerView适配器返回数据?

Android 如何从RecyclerView适配器返回数据?,android,android-recyclerview,Android,Android Recyclerview,我有一个RecyclerView,其中RecyclerView的每个对象中都有一个复选框。每次按下其中一个复选框时,我都希望在适配器上插入数据。有一次我完成了(按下片段上的一个按钮,将适配器设置为回收视图),必须返回数据 RecyclerView的适配器的我的代码(简化)是: public List<CarItem> data; public class MyCustomAdapter extends RecyclerView.Adapter<MyCustomAdapter.

我有一个
RecyclerView
,其中
RecyclerView
的每个对象中都有一个复选框。每次按下其中一个复选框时,我都希望在适配器上插入数据。有一次我完成了(按下片段上的一个按钮,将
适配器设置为
回收视图
),必须返回数据

RecyclerView
适配器的我的代码(简化)是:

public List<CarItem> data; 
public class MyCustomAdapter extends RecyclerView.Adapter<MyCustomAdapter.MyCustomViewHolder>  {

    public MyCustomAdapter(List<CarItem> data) {
        this.data=data;
    }

    public MyCustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout_car_item, parent, false);
        return new MyCustomViewHolder(view);
    }

    public void onBindViewHolder(final MyCustomViewHolder holder, final int position) {
        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                  @Override
                  public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                       //Here I add the data that I want to store
                       holder.getItem();
                  }
            });
    }

    public class MyCustomViewHolder extends RecyclerView.ViewHolder{
          public MyCustomViewHolder (View itemView) {
              super(itemView);
              //Here I make reference to all the elements of the layout of the Adapter
          }

          public void getItem(){
              Log.d("prove", "" + data.size());
          }
    }
}
公共列表数据;
公共类MyCustomAdapter扩展了RecyclerView.Adapter{
公共MyCustomAdapter(列表数据){
这个。数据=数据;
}
public MyCustomViewHolder onCreateViewHolder(视图组父级,int-viewType){
View=LayoutFlater.from(parent.getContext())。充气(R.layout\u car\u item,parent,false);
返回新的MyCustomViewHolder(视图);
}
公共无效onBindViewHolder(最终MyCustomViewHolder,最终int位置){
setOnCheckedChangeListener(newcompoundButton.OnCheckedChangeListener()){
setOnCheckedChangeListener(newcompoundButton.OnCheckedChangeListener()){
@凌驾
检查更改后的公共无效(复合按钮视图,布尔值已检查){
//在这里,我添加了要存储的数据
holder.getItem();
}
});
}
公共类MyCustomViewHolder扩展了RecyclerView.ViewHolder{
公共MyCustomViewHolder(查看项目视图){
超级(项目视图);
//这里我引用了适配器布局的所有元素
}
public void getItem(){
Log.d(“prove”,“data.size());
}
}
}
我已经创建了
getItem()
方法来获取
MyCustomViewHolder
中的数据,但我不知道如何将数据返回到
片段中,在该片段中,我将
适配器设置为
回收视图

是否有某种方法可以将数据从
RecyclerView
适配器
返回到我设置它的
片段


提前感谢!

不要使用
RecyclerView
。它不是专门为这种目的设计的。
RecyclerView
ListView
在您希望在回收行时显示只读数据时非常有用。使用这些视图从用户那里获取输入是危险的,因为当这些行在回收后被回收时滚动可能会丢失已输入的数据。请改用
LinearLayout
。这样,您可以直接访问其中的视图。如果要显示的绘图不是固定计数的,您可以动态地将
视图添加到容器中。

最简单的方法是使用EventBus

只需在片段中注册它并设置@Subscribe方法。 使用EventBus.getDefault().post(新建YourClass(yourData)),简单地构建类并将数据从适配器传递到片段

另一种方法是使用凹面

小心


当您要在适配器中使用复选框时,必须记住复选框中的旧值,并在列表滚动时设置。然后您可能会对SparseBooleanArray感兴趣。

更新的响应:

使用CarItems列表的备选方案:

@OnClick(...)
public void onButtonClicked() {
    int size = ((MyCustomAdapter) mRecyclerView.getAdapter()).getItemCount();
    for (int i = 0; i < size; i++) {
        if (((MyCustomAdapter) mRecyclerView.getAdapter()).isItemChecked(i)) {
            // Get each selected item
            CarItem carItem = (MyCustomAdapter) mRecyclerView.getAdapter()).getItem(i);
            // Do something with the item like save it to a selected items array.
        }
    }
}
然后从
RecyclerView
中使用它,如下所示:

((MyCustomAdapter) mRecyclerView.getAdapter()).getCheckedItems();

是否有某种方法可以从RecyclerView的适配器返回数据 我把它放在碎片上

通常要操作片段中的数据:

将下面的方法添加到适配器,并通过将其转换到自定义适配器的recyclerView从片段调用它们:
((MyCustomAdapter)mRecyclerView.getAdapter()).getItem(…);

有一次我做完了(按a) 将适配器设置为RecyclerView的片段上的按钮 必须返回数据

我需要额外的信息,了解返回数据时您尝试执行的操作,以及您下次将适配器设置为recyclerview的原因


我使用的是
RecyclerView
,因为我不知道从数据库检索时会有多少项目。我不知道是否可以使用
LinearLayout
@Kiril,有什么办法吗?我可以想象,对于某些目的,RecyclerView/Listview会非常有用。这是可能的。你只需要将vi充气即可EW(行)并将其放入<代码>线性布局< /代码>中,作为子<代码>视图>代码> .Error 404,我认为ReaveReVIEW多用途,这个答案不正确。我从来没有使用它来检查您的要求,我只使用它作为只读案例(所以我不投票)。但是,如果你在不知道物品数量的情况下采用这种方法,你将失去回收的好处,我认为所有可能的问题都可以解决。否则,Recyclerview将不存在。@adrock,我已经尝试过这种方法,而且效果很好。要保持滚动功能,应该将ListView放在滚动视图中(这对其他视图组容器也是有效的)我没有使用EventBus,但我使用了Otto,而且事情是异步发生的。我可能会变得非常混乱。因此,在使用总线时要小心。我更喜欢使用接口。如果你简化得更少,getItem()方法,也许我更理解你的问题。你是从数据库中检索数据吗?@Ardock是的,我是从数据库中检索数据。我现在明白了,我认为从数据库中加载数据,并且与视图持有者相比,不使用任何额外的数据结构来保存状态,这不是最好的方法,但我会尝试改进y响应以符合您的要求。我将创建一个额外列表以保存检索到的数据或使用caritems列表。您是否出于任何原因放弃此选项?@Ardock,因为项目的结构是由其他人完成的,我正在尝试获取
((MyCustomAdapter) mRecyclerView.getAdapter()).getCheckedItems();
public void setListItems(List<CarItem> data) {
    this.data = data;
}

public List getListItems() {
    return data;
}

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

public CarItem getItem(int position) {
    return data.get(position);
}

public void setItem(CarItem item, int position) {
    data.set(position, item);
}
public class MyCustomAdapter extends RecyclerView.Adapter<MyCustomAdapter.MyCustomViewHolder>  {
    private ArrayList<CarItem> data;
    private SparseBooleanArray checkedState = new SparseBooleanArray();

    public void setCheckedState(int position, boolean checked) {
        checkedState.append(position, checked);
    }

    public boolean isItemChecked(int position) {
        return checkedState.get(position);
    }

    public SparseBooleanArray getCheckedState() {
        return checkedState;
    }

    public void onBindViewHolder(final MyCustomViewHolder holder, final int position) {
        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                  @Override
                  public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                       setCheckedState(holder.getAdapterPosition(), isChecked);
                       //Here I add the data that I want to store
                       if (isChecked) {
                           data.set(holder.getAdapterPosition(), holder.getItem());
                       } else {
                           data.set(holder.getAdapterPosition(), null);
                       }

              }
        });
}
viewHolder.itemView.setTag(yourNewData);

/**
 * Returns this view's tag.
 *
 * @return the Object stored in this view as a tag, or {@code null} if not
 *         set
 *
 * @see #setTag(Object)
 * @see #getTag(int)
 */
@ViewDebug.ExportedProperty
public Object getTag() {
    return mTag;
}

/**
 * Sets the tag associated with this view. A tag can be used to mark
 * a view in its hierarchy and does not have to be unique within the
 * hierarchy. Tags can also be used to store data within a view without
 * resorting to another data structure.
 *
 * @param tag an Object to tag the view with
 *
 * @see #getTag()
 * @see #setTag(int, Object)
 */
public void setTag(final Object tag) {
    mTag = tag;
}
/**
 * Return the ViewHolder for the item in the given position of the data set. Unlike
 * {@link #findViewHolderForLayoutPosition(int)} this method takes into account any pending
 * adapter changes that may not be reflected to the layout yet. On the other hand, if
 * {@link Adapter#notifyDataSetChanged()} has been called but the new layout has not been
 * calculated yet, this method will return <code>null</code> since the new positions of views
 * are unknown until the layout is calculated.
 * <p>
 * This method checks only the children of RecyclerView. If the item at the given
 * <code>position</code> is not laid out, it <em>will not</em> create a new one.
 *
 * @param position The position of the item in the data set of the adapter
 * @return The ViewHolder at <code>position</code> or null if there is no such item
 */
public ViewHolder findViewHolderForAdapterPosition(int position) {
    if (mDataSetHasChangedAfterLayout) {
        return null;
    }
    final int childCount = mChildHelper.getUnfilteredChildCount();
    for (int i = 0; i < childCount; i++) {
        final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
        if (holder != null && !holder.isRemoved() && getAdapterPositionFor(holder) == position) {
            return holder;
        }
    }
    return null;
}

@OnClick(...)
public void onButtonClicked() {
    int size = ((MyCustomAdapter) mRecyclerView.getAdapter()).getItemCount();
    for (int i = 0; i < size; i++) {
        ViewHolder vh = (MyCustomViewHolder) findViewHolderForAdapterPosition(i);
        if (vh != null && ((MyCustomAdapter) mRecyclerView.getAdapter()).isItemChecked(i)) {
            Object obj = vh.itemView.getTag();
            // Manipulate the data contained in this view holder
            // but perhaps would be better to save the data in the CarItem
            // and don't manipulate the VH from outside the adapter
        }
    }
}