Transfer Items from one Recyclerview to another and vice versa.

Hello Guys,

We have many examples of swiping up & down and left & right or exchanging of data items/rows in same recyclerview.

Now what if you have to exchange data item/row between two recyclerviews.

So in this post, we will see exchange of items from one recyclerview to another and vice versa.
In this we have used concept of Data Binding (please refer Data Binding (MVVM) I/O 2016).

1) One side/way transfer :

Here we have taken two recyclerviews, one at bottom (Vertical) and second one at top (Horizontal).
In this we will transfer data item of Vertical Recyclerview to Horizontal Recyclerview.

Please see the sequence of the pics :

MainActivity

main_screen.png

 

 

Selecting Item

selected_item.png

 

Dropping Item to another Recyclerview

dropping_item.png

 
Item in another Recyclerview

item_in_another_recylerview.png

 

Multiple Items in Second Recyclerview

multiple_items_seocnd_recyclerview.png

 

Now how we did it is much important, please look at the below steps :

1) We have to implement OnDragListener of View in our Main Activity.
(This listener gives us access to drag and drop the views with it events).

2) Setting the this drag listener on recyclerview (where we have to set dragged items, in our case its Horizontal Recylerview).

3) And the items which are to be dragged (Vertical Recyclerview Items), so we have set long click on it in ExcercieListAdapter.
So that it will get selected and make it able to move.

4) In Drag listener we will get the position of item long clicked.

5) In Action_Drop event, we will get the item moved, so that we can remove the item from ExerciseList (Main List of all items) and add it to exerciseSelectedList.
And finally updating the adapter.

6) In Action_Drag_Ended, making the selected item visible, so that if user does not move it to another recyclerview, then it should be placed to its original position.

To make this all we have taken two recyclerviews, two different layout for row items, one adapter which manages both the recyclerview.

Main Activity

package com.example.recyclerviewexchangeitems;

import android.databinding.DataBindingUtil;
import android.databinding.ObservableArrayList;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.DragEvent;
import android.view.View;

import com.example.recyclerviewexchangeitems.databinding.MainActivityBinding;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements View.OnDragListener {

    private MainActivityBinding mainActivityBinding;
    public ObservableArrayList<ExcercisePojo> exerciseList;
    public ObservableArrayList<ExcercisePojo> exerciseSelectedList = new ObservableArrayList<>();
    public ExcercisePojo exerciseToMove;
    private int newContactPosition = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainActivityBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        loadExerciseData();
        mainActivityBinding.setMainActivity(this);
        mainActivityBinding.rcvSelectedExercise.setOnDragListener(this);
    }


    public void loadExerciseData() {
        exerciseList = new ObservableArrayList<>();
        for (int i = 1; i <= 10; i++) {
            exerciseList.add(new ExcercisePojo(i, "exercise " + i));
        }
    }

    @Override
    public boolean onDrag(View view, DragEvent dragEvent) {
        View selectedView = (View) dragEvent.getLocalState();
        RecyclerView rcvSelected = (RecyclerView) view;
        int currentPosition = -1;
        try {
            currentPosition = mainActivityBinding.rcvChooseExercise.getChildAdapterPosition(selectedView);

            // Ensure the position is valid.
            if (currentPosition != -1) {
                exerciseToMove = exerciseList.get(currentPosition);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        switch (dragEvent.getAction()) {
            case DragEvent.ACTION_DRAG_LOCATION:
                View onTopOf = rcvSelected.findChildViewUnder(dragEvent.getX(), dragEvent.getY());
                newContactPosition = rcvSelected.getChildAdapterPosition(onTopOf);
                break;
            case DragEvent.ACTION_DRAG_ENTERED:
                break;
            case DragEvent.ACTION_DRAG_EXITED:
                break;
            case DragEvent.ACTION_DROP:
                //when Item is dropped off to recyclerview.
                exerciseSelectedList.add(exerciseToMove);
                exerciseList.remove(exerciseToMove);
                mainActivityBinding.rcvChooseExercise.getAdapter().notifyItemRemoved(currentPosition);
                mainActivityBinding.executePendingBindings();

                //This is to hide/add the container!
                /*ViewGroup owner = (ViewGroup) (view.getParent());
                if (owner != null) {
                    //owner.removeView(selectedView);
                    //owner.addView(selectedView);

                    try {
                        LinearLayout rlContainer = (LinearLayout) view;
                        rlContainer.addView(selectedView);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //selectedView.setVisibility(View.VISIBLE);
                }*/

                break;

            case DragEvent.ACTION_DRAG_ENDED:
                // Reset the visibility for the Contact item's view.
                // This is done to reset the state in instances where the drag action didn't do anything.
                selectedView.setVisibility(View.VISIBLE);
                // Boundary condition, scroll to top is moving list item to position 0.
                if (newContactPosition != -1) {
                    rcvSelected.scrollToPosition(newContactPosition);
                    newContactPosition = -1;
                } else {
                    rcvSelected.scrollToPosition(0);
                }
            default:
                break;
        }
        return true;
    }
}

 

ExercisePojo

package com.example.recyclerviewexchangeitems;

/**
 * Created by Sumeet on 16-07-2017.
 */

public class ExcercisePojo {
    public int exerciseId;
    public String name;

    public ExcercisePojo(int exerciseId, String name) {
        this.exerciseId = exerciseId;
        this.name = name;
    }
}

 

ExerciseListAdapter

package com.example.recyclerviewexchangeitems;

import android.content.ClipData;
import android.content.Context;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableArrayList;
import android.databinding.ObservableList;
import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.recyclerviewexchangeitems.databinding.ChooseExerciseItemBinding;
import com.example.recyclerviewexchangeitems.databinding.SelectedExerciseItemBinding;

/**
 * Created by Sumeet on 16-07-2017.
 */

public class ExcerciseListAdapter extends RecyclerView.Adapter<ExcerciseListAdapter.ProjectHolder> {

    private ObservableList<ExcercisePojo> exerciseObservableList = new ObservableArrayList<>();
    private Context context;
    private RecyclerView recyclerExercise;
    private int layoutId;

    public ExcerciseListAdapter(RecyclerView recyclerExercise, ObservableArrayList<ExcercisePojo> exerciseObservableList, int layoutId) {
        this.exerciseObservableList = exerciseObservableList;
        this.recyclerExercise = recyclerExercise;
        this.layoutId = layoutId;
    }

    @Override
    public ProjectHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
        context = parent.getContext();
        return new ProjectHolder(v);
    }

    @Override
    public void onBindViewHolder(ProjectHolder holder, int position) {
        final ExcercisePojo excercisePojo = exerciseObservableList.get(position);
        if (layoutId == R.layout.layout_choose_exercise_item) {
            ChooseExerciseItemBinding chooseExerciseItemBinding = (ChooseExerciseItemBinding) holder.chooseExerciseItemBinding;
            chooseExerciseItemBinding.setExercise(excercisePojo);
            chooseExerciseItemBinding.setChooseExerciseListAdapter(this);
        } else {
            SelectedExerciseItemBinding selectedExerciseItemBinding = (SelectedExerciseItemBinding) holder.chooseExerciseItemBinding;
            selectedExerciseItemBinding.setExercise(excercisePojo);
            selectedExerciseItemBinding.setChooseExerciseListAdapter(this);
        }
        holder.chooseExerciseItemBinding.executePendingBindings();
    }

    @Override
    public int getItemCount() {
        if (exerciseObservableList == null) {
            return 0;
        }
        return exerciseObservableList.size();
    }

    public class ProjectHolder extends RecyclerView.ViewHolder {
        public ViewDataBinding chooseExerciseItemBinding;

        public ProjectHolder(View itemView) {
            super(itemView);
            chooseExerciseItemBinding = DataBindingUtil.bind(itemView);
        }
    }


    public boolean onLongClick(View view) {
        ClipData data = ClipData.newPlainText("", "");
        View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
        view.startDrag(data, shadowBuilder, view, 0);
        view.setVisibility(View.INVISIBLE);
        return true;
    }

   /* public void onListItemClick(View view) {
        Intent intent = new Intent(context, ExerciseCategoryDetail.class);
        Bundle bundle = new Bundle();
        int position = recyclerExercise.getChildLayoutPosition(view);
        //Utils.makeShortToast(context, "pos : " + position);
        ExerciseCategoryPojo excercisePojo = exerciseObservableList.get(position);
        bundle.putParcelable(Constants.EXCERCISE_CATEGORY_OBJ, excercisePojo);
        bundle.putBoolean(Constants.CAN_ADD_EXERCISE, true);
        intent.putExtras(bundle);
        context.startActivity(intent);
    }
*/

}

 
BindingUtils

package com.example.recyclerviewexchangeitems;

import android.databinding.BindingAdapter;
import android.databinding.ObservableArrayList;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

/**
 * Created by Sumeet on 16-07-2017.
 */

public class BindingUtils {

    @BindingAdapter({"bind:exerciseChooseItems", "bind:layoutId"})
    public static void bindExerciseList(RecyclerView view, ObservableArrayList<ExcercisePojo> list, int layoutId) {
        GridLayoutManager layoutManager = new GridLayoutManager(view.getContext(), 3);
        view.setLayoutManager(layoutManager);
        view.setAdapter(new ExcerciseListAdapter(view, list, layoutId));
    }


    @BindingAdapter({"bind:exerciseHorizontalItems", "bind:layoutId"})
    public static void bindHorizontalList(RecyclerView view, ObservableArrayList<ExcercisePojo> list, int layoutId) {
        LinearLayoutManager layoutManager = new LinearLayoutManager(view.getContext(), LinearLayoutManager.HORIZONTAL, false);
        view.setLayoutManager(layoutManager);
        view.setAdapter(new ExcerciseListAdapter(view, list, layoutId));
    }

}

 

drawable/shape_pink_circle.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <!--<stroke android:width="1dp" />-->

    <solid android:color="@color/colorAccent" />
</shape>

 

drawable/shape_purple_circle.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <!--<stroke android:width="1dp" />-->

    <solid android:color="@color/dark_purple" />

</shape>

 

layout/activity_main

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data class="MainActivityBinding">

        <import type="com.example.recyclerviewexchangeitems.R" />

        <!--<variable
            name="chooseExerciseFragment"
            type="com.stepett.app.fragments.excercise.ChooseExerciseFragment" />-->

        <variable
            name="mainActivity"
            type="com.example.recyclerviewexchangeitems.MainActivity" />

    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <View
            android:id="@+id/view1"
            android:layout_width="match_parent"
            android:layout_height="@dimen/scale_1dp"
            android:layout_marginTop="@dimen/scale_20dp"
            android:background="@color/colorPrimaryDark" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rcv_selected_exercise"
            android:layout_width="match_parent"
            android:layout_height="@dimen/scale_110dp"
            android:layout_below="@id/view1"
            android:paddingTop="@dimen/scale_10dp"
            app:exerciseHorizontalItems="@{mainActivity.exerciseSelectedList}"
            app:layoutId="@{R.layout.layout_selected_exercise_item}" />


        <View
            android:id="@+id/view2"
            android:layout_width="match_parent"
            android:layout_height="@dimen/scale_1dp"
            android:layout_below="@id/rcv_selected_exercise"
            android:background="@color/colorPrimaryDark" />

        <LinearLayout
            android:id="@+id/ll_filter_exrecise"
            android:layout_width="match_parent"
            android:layout_height="@dimen/scale_40dp"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="@dimen/scale_10dp"
            android:orientation="vertical">

        </LinearLayout>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rcv_choose_exercise"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@id/ll_filter_exrecise"
            android:layout_below="@id/view2"
            android:layout_marginBottom="@dimen/scale_10dp"
            android:layout_marginTop="@dimen/scale_10dp"
            app:exerciseChooseItems="@{mainActivity.exerciseList}"
            app:layoutId="@{R.layout.layout_choose_exercise_item}" />


    </RelativeLayout>
</layout>

layout/layout_choose_exercise_item.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data class="ChooseExerciseItemBinding">

        <variable
            name="exercise"
            type="com.example.recyclerviewexchangeitems.ExcercisePojo" />

        <variable
            name="chooseExerciseListAdapter"
            type="com.example.recyclerviewexchangeitems.ExcerciseListAdapter" />

    </data>

    <RelativeLayout
        android:id="@+id/rl_exercise_type"
        android:layout_width="@dimen/scale_95dp"
        android:layout_height="@dimen/scale_90dp"
        android:background="@drawable/shape_purple_circle"
        android:gravity="center"
        android:onLongClick="@{chooseExerciseListAdapter.onLongClick}">

        <!--android:onClick="@{chooseExerciseListAdapter.onListItemClick}"-->


        <TextView
            android:id="@+id/tv_exercise_type"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@{exercise.name}"
            android:textAllCaps="true"
            android:textColor="@color/white"
            android:textSize="@dimen/txt_12sp" />

    </RelativeLayout>

</layout>

layout/layout_selected_exercise_item.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data class="SelectedExerciseItemBinding">

        <variable
            name="exercise"
            type="com.example.recyclerviewexchangeitems.ExcercisePojo" />

        <variable
            name="chooseExerciseListAdapter"
            type="com.example.recyclerviewexchangeitems.ExcerciseListAdapter" />

    </data>

    <RelativeLayout
        android:id="@+id/rl_exercise_type"
        android:layout_width="@dimen/scale_95dp"
        android:layout_height="@dimen/scale_90dp"
        android:layout_marginLeft="@dimen/scale_10dp"
        android:background="@drawable/shape_pink_circle"
        android:gravity="center">
        <!--android:onLongClick="@{chooseExerciseListAdapter.onLongClick}"-->


        <TextView
            android:id="@+id/tv_exercise_type"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@{exercise.name}"
            android:textAllCaps="true"
            android:textColor="@color/white"
            android:textSize="@dimen/txt_12sp" />

    </RelativeLayout>

</layout>

 

Please find code at :
https://github.com/Sunny1989/RecyclerviewExchangeItems

 

2) Two side/way transfer :

In this we will exchange items of both the recyclerviews (Vertical and Horizontal).

For this we have to make following changes:

1) Implement OndragListener for both Recyclerview.
Here we have added one more listener (for Vertical Recyclerview).

2) We have to implement onLongClick for both the recyclerviews items.

Please check the following code changes :

Main Activity

package com.example.recyclerviewtwowayexchangeitems;

import android.databinding.DataBindingUtil;
import android.databinding.ObservableArrayList;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.DragEvent;
import android.view.View;

import com.example.recyclerviewtwowayexchangeitems.databinding.MainActivityBinding;

public class MainActivity extends AppCompatActivity implements View.OnDragListener {

    private MainActivityBinding mainActivityBinding;
    public ObservableArrayList<ExcercisePojo> exerciseList;
    public ObservableArrayList<ExcercisePojo> exerciseSelectedList = new ObservableArrayList<>();
    public ExcercisePojo exerciseToMove;
    private int newContactPosition = -1;

    private int currentPosition = -1;
    private boolean isExerciseAdded = false;
    public static boolean isFromExercise = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainActivityBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        loadExerciseData();
        mainActivityBinding.setMainActivity(this);
        mainActivityBinding.rcvSelectedExercise.setOnDragListener(this);


        mainActivityBinding.rcvChooseExercise.setOnDragListener(new MyDragInsideRcvListener());
        int spacingInPixels = getResources().getDimensionPixelSize(R.dimen.scale_3dp);
        mainActivityBinding.rcvChooseExercise.addItemDecoration(new SpaceItemDecoration(spacingInPixels));
    }


    public void loadExerciseData() {
        exerciseList = new ObservableArrayList<>();
        for (int i = 1; i <= 10; i++) {
            exerciseList.add(new ExcercisePojo(i, "exercise " + i));
        }
    }

    @Override
    public boolean onDrag(View view, DragEvent dragEvent) {
        View selectedView = (View) dragEvent.getLocalState();
        RecyclerView rcvSelected = (RecyclerView) view;

        try {
            int currentPosition = mainActivityBinding.rcvChooseExercise.getChildAdapterPosition(selectedView);

            // Ensure the position is valid.
            if (currentPosition != -1) {
                exerciseToMove = exerciseList.get(currentPosition);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        switch (dragEvent.getAction()) {
            case DragEvent.ACTION_DRAG_LOCATION:
                View onTopOf = rcvSelected.findChildViewUnder(dragEvent.getX(), dragEvent.getY());
                newContactPosition = rcvSelected.getChildAdapterPosition(onTopOf);
                break;
            case DragEvent.ACTION_DRAG_ENTERED:
                break;
            case DragEvent.ACTION_DRAG_EXITED:
                break;
            case DragEvent.ACTION_DROP:
                //when Item is dropped off to recyclerview.
                if (isFromExercise) {
                    exerciseSelectedList.add(exerciseToMove);
                    exerciseList.remove(exerciseToMove);
                    mainActivityBinding.rcvChooseExercise.getAdapter().notifyItemRemoved(currentPosition);
                    mainActivityBinding.executePendingBindings();
                }
                //This is to hide/add the container!
                /*ViewGroup owner = (ViewGroup) (view.getParent());
                if (owner != null) {
                    //owner.removeView(selectedView);
                    //owner.addView(selectedView);

                    try {
                        LinearLayout rlContainer = (LinearLayout) view;
                        rlContainer.addView(selectedView);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //selectedView.setVisibility(View.VISIBLE);
                }*/

                break;

            case DragEvent.ACTION_DRAG_ENDED:
                // Reset the visibility for the Contact item's view.
                // This is done to reset the state in instances where the drag action didn't do anything.
                selectedView.setVisibility(View.VISIBLE);
                // Boundary condition, scroll to top is moving list item to position 0.
                if (newContactPosition != -1) {
                    rcvSelected.scrollToPosition(newContactPosition);
                    newContactPosition = -1;
                } else {
                    rcvSelected.scrollToPosition(0);
                }
            default:
                break;
        }
        return true;
    }

    /**
     * This listener class is for Vertical Recyclerview.
     */
    class MyDragInsideRcvListener implements View.OnDragListener {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            int action = event.getAction();
            RecyclerView rcv = (RecyclerView) v;

            View selectedView = (View) event.getLocalState();
            try {
                int currentPosition = rcv.getChildAdapterPosition(selectedView);
                // Ensure the position is valid.
                if (currentPosition != -1) {
                    exerciseToMove = exerciseSelectedList.get(currentPosition);
                    //exerciseSelectedList.get(currentPosition);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            switch (event.getAction()) {
                case DragEvent.ACTION_DRAG_LOCATION:
                    View onTopOf = rcv.findChildViewUnder(event.getX(), event.getY());
                    newContactPosition = rcv.getChildAdapterPosition(onTopOf);

                    //Flag for our own understanding!
                    //isFromExercise = true;

                    //This is for internal dragging (inside recyclerview only).  VVIP!
                    // Ensure the new position is valid.

                    //If you wanted to swap the items in recyclerview only.
                    //It requires bit changes.
                   /* if (newContactPosition != -1) {
                        LinearLayoutManager layoutManager = (LinearLayoutManager) rcv.getLayoutManager();
                        int firstVisiblePosition = layoutManager.findFirstCompletelyVisibleItemPosition();
                        int lastVisiblePosition = layoutManager.findLastVisibleItemPosition();

                        // Scroll up or down one if we are over the first or last visible list item.
                        if (newContactPosition >= lastVisiblePosition)
                            layoutManager.scrollToPositionWithOffset(firstVisiblePosition + 1, 0);
                        else if (newContactPosition <= firstVisiblePosition)
                            layoutManager.scrollToPositionWithOffset(firstVisiblePosition - 1, 0);

                        // Update the location of the Contact
                        exerciseList.remove(exerciseToMove);
                        exerciseList.add(newContactPosition, exerciseToMove);
                        rcv.getAdapter().notifyDataSetChanged();
                    }*/
                    break;
                case DragEvent.ACTION_DRAG_ENDED:
                    // Reset the visibility for the Contact item's view.
                    // This is done to reset the state in instances where the drag action didn't do anything.
                    selectedView.setVisibility(View.VISIBLE);
                    // Boundary condition, scroll to top is moving list item to position 0.
                    if (newContactPosition != -1) {
                        rcv.scrollToPosition(newContactPosition);
                        newContactPosition = -1;
                    } else {
                        rcv.scrollToPosition(0);
                    }
                    break;
                case DragEvent.ACTION_DROP:
                    if (!isFromExercise) {
                        //THIS IS FOR WHEN WE TAKE ITEM OF OTHER LIST AND DROP IN THIS LIST.
                        exerciseList.add(exerciseToMove);
                        exerciseSelectedList.remove(exerciseToMove);
                        mainActivityBinding.rcvChooseExercise.getAdapter().notifyItemInserted(currentPosition);
                        mainActivityBinding.executePendingBindings();
                    }
                    break;

                default:
                    break;
            }
            return true;
        }
    }
}

And in this I have also included the code to swap the data items (Vertical Recyclerview).
This code is commented (as it requires bit changes), but it can be used.
In MyDragInsideRcvListener, check the commented code in DragEvent.ACTION_DRAG_LOCATION and it swaps the items within recycelrview area.

To use it, just remove comments the code.
Check the following screen shots of internal swapping of items :

Exercise 9 is selected to swap internally

swap2.png
Exercise 9 , is placed at Exercise 8.

sawp3.png

 

ExerciseListAdapter

package com.example.recyclerviewtwowayexchangeitems;

import android.content.ClipData;
import android.content.Context;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableArrayList;
import android.databinding.ObservableList;
import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.recyclerviewtwowayexchangeitems.databinding.ChooseExerciseItemBinding;
import com.example.recyclerviewtwowayexchangeitems.databinding.SelectedExerciseItemBinding;

/**
 * Created by Sumeet on 16-07-2017.
 */

public class ExcerciseListAdapter extends RecyclerView.Adapter<ExcerciseListAdapter.ProjectHolder> {

    private ObservableList<ExcercisePojo> exerciseObservableList = new ObservableArrayList<>();
    private Context context;
    private RecyclerView recyclerExercise;
    private int layoutId;

    public ExcerciseListAdapter(RecyclerView recyclerExercise, ObservableArrayList<ExcercisePojo> exerciseObservableList, int layoutId) {
        this.exerciseObservableList = exerciseObservableList;
        this.recyclerExercise = recyclerExercise;
        this.layoutId = layoutId;
    }

    @Override
    public ProjectHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
        context = parent.getContext();
        return new ProjectHolder(v);
    }

    @Override
    public void onBindViewHolder(ProjectHolder holder, int position) {
        final ExcercisePojo excercisePojo = exerciseObservableList.get(position);
        if (layoutId == R.layout.layout_choose_exercise_item) {
            ChooseExerciseItemBinding chooseExerciseItemBinding = (ChooseExerciseItemBinding) holder.chooseExerciseItemBinding;
            chooseExerciseItemBinding.setExercise(excercisePojo);
            chooseExerciseItemBinding.setChooseExerciseListAdapter(this);
        } else {
            SelectedExerciseItemBinding selectedExerciseItemBinding = (SelectedExerciseItemBinding) holder.chooseExerciseItemBinding;
            selectedExerciseItemBinding.setExercise(excercisePojo);
            selectedExerciseItemBinding.setChooseExerciseListAdapter(this);
        }
        holder.chooseExerciseItemBinding.executePendingBindings();
    }

    @Override
    public int getItemCount() {
        if (exerciseObservableList == null) {
            return 0;
        }
        return exerciseObservableList.size();
    }

    public class ProjectHolder extends RecyclerView.ViewHolder {
        public ViewDataBinding chooseExerciseItemBinding;

        public ProjectHolder(View itemView) {
            super(itemView);
            chooseExerciseItemBinding = DataBindingUtil.bind(itemView);
        }
    }


    public boolean onLongClick(View view) {
        ClipData data = ClipData.newPlainText("", "");
        View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
        view.startDrag(data, shadowBuilder, view, 0);
        view.setVisibility(View.INVISIBLE);
        if (layoutId == R.layout.layout_choose_exercise_item) {
            MainActivity.isFromExercise = true;
        } else {
            MainActivity.isFromExercise = false;
        }
        return true;
    }

   /* public void onListItemClick(View view) {
        Intent intent = new Intent(context, ExerciseCategoryDetail.class);
        Bundle bundle = new Bundle();
        int position = recyclerExercise.getChildLayoutPosition(view);
        //Utils.makeShortToast(context, "pos : " + position);
        ExerciseCategoryPojo excercisePojo = exerciseObservableList.get(position);
        bundle.putParcelable(Constants.EXCERCISE_CATEGORY_OBJ, excercisePojo);
        bundle.putBoolean(Constants.CAN_ADD_EXERCISE, true);
        intent.putExtras(bundle);
        context.startActivity(intent);
    }
*/

}

 
layout/layout_choose_exercise_item.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data class="ChooseExerciseItemBinding">

        <variable
            name="exercise"
            type="com.example.recyclerviewtwowayexchangeitems.ExcercisePojo" />

        <variable
            name="chooseExerciseListAdapter"
            type="com.example.recyclerviewtwowayexchangeitems.ExcerciseListAdapter" />

    </data>

    <RelativeLayout
        android:id="@+id/rl_exercise_type"
        android:layout_width="@dimen/scale_95dp"
        android:layout_height="@dimen/scale_90dp"
        android:background="@drawable/shape_purple_circle"
        android:gravity="center"
        android:onLongClick="@{chooseExerciseListAdapter.onLongClick}">

        <!--android:onClick="@{chooseExerciseListAdapter.onListItemClick}"-->


        <TextView
            android:id="@+id/tv_exercise_type"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@{exercise.name}"
            android:textAllCaps="true"
            android:textColor="@color/white"
            android:textSize="@dimen/txt_12sp" />

    </RelativeLayout>

</layout>

layout/layout_selected_exercise_item.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data class="SelectedExerciseItemBinding">

        <variable
            name="exercise"
            type="com.example.recyclerviewtwowayexchangeitems.ExcercisePojo" />

        <variable
            name="chooseExerciseListAdapter"
            type="com.example.recyclerviewtwowayexchangeitems.ExcerciseListAdapter" />

    </data>

    <RelativeLayout
        android:id="@+id/rl_exercise_type"
        android:layout_width="@dimen/scale_95dp"
        android:layout_height="@dimen/scale_90dp"
        android:layout_marginLeft="@dimen/scale_10dp"
        android:background="@drawable/shape_pink_circle"
        android:gravity="center"
        android:onLongClick="@{chooseExerciseListAdapter.onLongClick}">


        <TextView
            android:id="@+id/tv_exercise_type"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@{exercise.name}"
            android:textAllCaps="true"
            android:textColor="@color/white"
            android:textSize="@dimen/txt_12sp" />

    </RelativeLayout>

</layout>

Rest other part of code is same as above example.

Check the screen shots :

Putting an item from vertical Recyclerview to Horizontal Recyclerview

two_way1.png

Selecting Exercise 2 and putting back in Vertical Recyclerview.

two_way2.png

 

Putting from Vertical to Horizontal Recylerview

two_way4.png

 

two_way5.png

 

Please find the code at :
https://github.com/Sunny1989/RecyclerviewTwoWayExchangeItems

References :
1) https://www.linkedin.com/pulse/new-tutorial-implement-custom-drag-drop-recycler-view-jonathan-beck

2) https://developer.android.com/guide/topics/ui/drag-drop.html

Kindly let me know for any concern.

Thank you. 🙂

Leave a comment