Skip to content
Advertisement

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.

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.

Advertisement

Answer

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.

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.

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. 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().

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement