简体   繁体   English

将数据从 RecyclerView 传递到片段中的另一个

[英]Pass data from RecyclerView to another in fragment

i want to pass data from recyclerview to another both in fragment, first adapter for display item, and second adapter for basket fragment that want to put selected item in.我想将数据从 recyclerview 传递给另一个片段,第一个适配器用于显示项目,第二个适配器用于篮子片段,想要放入选定的项目。

Adapter I want to take data from我想从中获取数据的适配器

public class FruitItemAdapter extends RecyclerView.Adapter<FruitItemAdapter.viewHolder> {

    ArrayList<FruitItem> fruitItems = new ArrayList<>();
    private Context context;

    public FruitItemAdapter(ArrayList<FruitItem> fruitItems, Context context) {
        this.fruitItems = fruitItems;
        this.context = context;
        notifyDataSetChanged();
    }

    public FruitItemAdapter() {
    
    }

    @NonNull
    @Override
    public viewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = 
LayoutInflater.from(parent.getContext()).inflate(R.layout.fruits_item,parent,false);
        viewHolder viewHolder = new viewHolder(view);

        return viewHolder;

    }

    @Override
    public void onBindViewHolder(@NonNull viewHolder holder, int position) {

        final FruitItem data_position = fruitItems.get(position);

        holder.fruit_img.setImageResource(fruitItems.get(position).getFruit_img());
        holder.fruit_name.setText(fruitItems.get(position).getFruit_name());
        holder.fruit_price.setText(fruitItems.get(position).getFruit_price());

    }

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

    public void setfruitItem(ArrayList<FruitItem> fruitItems) {
        this.fruitItems = fruitItems;
    }



    public static class viewHolder extends RecyclerView.ViewHolder {

        private ImageView fruit_img;
        private  TextView fruit_price, fruit_name;
    

        public viewHolder(@NonNull View itemView) {
            super(itemView);

            fruit_img = itemView.findViewById(R.id.fruit_img);
            fruit_price = itemView.findViewById(R.id.fruit_price);
            fruit_name = itemView.findViewById(R.id.fruit_name)


        }
   
    }
}

this is adapter for basket fragment that I want to put the data in这是我要放入数据的篮子片段的适配器

public class Basket_Adapter extends RecyclerView.Adapter<Basket_Adapter.viewHolder> {

    private Context context;
    ArrayList<FruitItem> fruitItems = new ArrayList<>();

    public Basket_Adapter(Context context, ArrayList<FruitItem> fruitItems) {
        this.context = context;
        this.fruitItems = fruitItems;
        notifyDataSetChanged();
    }

    public Basket_Adapter(){

    }
@NonNull
 @Override
  public Basket_Adapter.viewHolder onCreateViewHolder(@NonNull ViewGroup parent, int   
  viewType) {
        
  
View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.fruits_item,parent,false);
viewHolder viewHolder = new viewHolder(view);

      return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull Basket_Adapter.viewHolder holder, int position) {


        holder.fruit_img.setImageResource(fruitItems.get(position).getFruit_img());
        holder.fruit_name.setText(fruitItems.get(position).getFruit_name());
        holder.fruit_price.setText(fruitItems.get(position).getFruit_price());


    }

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

    public void setfruitItem(ArrayList<FruitItem> fruitItems) {
        this.fruitItems = fruitItems;
    }

    public class viewHolder extends RecyclerView.ViewHolder {

        private ImageView fruit_img;
        private TextView fruit_name;
        private TextView fruit_price;

        public viewHolder(@NonNull View itemView) {
            super(itemView);

            fruit_img = itemView.findViewById(R.id.fruit_img);
            fruit_name = itemView.findViewById(R.id.fruit_name);
            fruit_price = itemView.findViewById(R.id.fruit_price);
         
        }
    }

Now, what i can use to pass data between them.现在,我可以用来在它们之间传递数据。

You can achieve this by using the delegation pattern .您可以通过使用委托模式来实现这一点。 Basically you create an interface relative to the first adapter (you can put it inside the adapter class or outside depending on your coding style) and you require it as an argument inside the adapter constructor like this:基本上,您创建一个相对于第一个适配器的接口(您可以将它放在适配器类内部或外部,具体取决于您的编码风格),并且您需要它作为适配器构造函数中的参数,如下所示:

public class FruitItemAdapter extends RecyclerView.Adapter<FruitItemAdapter.viewHolder> {

    private Delegate delegate;
    ArrayList<FruitItem> fruitItems = new ArrayList<>();
    private Context context;

    public FruitItemAdapter(Delegate delegate, ArrayList<FruitItem> fruitItems, Context context) {
        this.delegate = delegate;
        this.fruitItems = fruitItems;
        this.context = context;
        notifyDataSetChanged();
    }

    ...

    interface Delegate {
        public void passItem(FruitItem item);
    }
}

As you can see the interface has the method you need, but there's no implementation yet.如您所见,接口具有您需要的方法,但还没有实现。 In this class you can just pretend that your delegate works and do the magic for you, for example by setting a click listener on the root view of your item in onBindViewHolder that will call delegate.passItem(fruitItems.get(position)) on each click.在这个类中,您可以假装您的委托为您工作并为您施展魔法,例如通过在 onBindViewHolder 中您的项目的根视图上设置一个单击侦听器,该侦听器将在每个项目上调用delegate.passItem(fruitItems.get(position))点击。

Let's move on to the fragment.让我们继续讨论片段。

Here is the key part.这是关键部分。 The fragment must implement the interface we just created by overriding its methods.片段必须通过覆盖其方法来实现我们刚刚创建的接口。 Like so:像这样:

class ExampleFragment extends Fragment implements FruitItemAdapter.Delegate {

    ...

    @Override
    public void passItem(FruitItem item) {
        // here you pass the item in a list inside
        // the shared preferences.
    }
}

For your case the best way is to store your items in a database or in the shared preferences .对于您的情况,最好的方法是将您的项目存储在数据库或共享首选项中。 We go with the shared preferences because is simpler, but keep in mind that shared preferences have limited memory capacity and you should use a database like Room instead.我们使用共享首选项是因为它更简单,但请记住,共享首选项的内存容量有限,您应该使用像Room这样的数据库。

Inside the override method you pass your item to a list stored in the shared preferences.在覆盖方法中,您将项目传递给存储在共享首选项中的列表。 Since your item is not a primitive object i suggest you to look at this answer that show how to store complex object as a string: https://stackoverflow.com/a/18463758/18740763 .由于您的项目不是原始对象,我建议您查看显示如何将复杂对象存储为字符串的答案: https ://stackoverflow.com/a/18463758/18740763。 In your case the object that needs to be serialized is an Array or a List of objects.在您的情况下,需要序列化的对象是数组或对象列表。

Every time you need to put a new object in the list you need to follow these steps:每次需要在列表中添加新对象时,都需要执行以下步骤:

  1. get the list from shared preferences从共享首选项中获取列表
  2. deserialize it反序列化它
  3. add the new item添加新项目
  4. serialize it again再次序列化
  5. put it back in the shared preferences under the same key将其放回共享首选项中的同一键下

If you stored your items correctly now you should be able to access the shared list in every fragment or activity of your application.如果您现在正确存储了项目,您应该能够访问应用程序的每个片段或活动中的共享列表。 So simply access your list from the fragment that implements the second adapter, deserialize it, just addAll() the items the the adapter list and notifyDataSetChanged() .因此,只需从实现第二个适配器的片段中访问您的列表,反序列化它,只需addAll()适配器列表和notifyDataSetChanged()中的项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM