Android Arraylist с возможностью Drag and drop

Как сделать Fragment с RecyclerView в котором будет Arraylist с MaterialCardView в котором будут TextView и ImageView но при этом при нажатии на ImageView можно перетаскивать по RecyclerView меняя местами с другими MaterialCardView.То есть Drag and drop. В примере material-components-android используется generateCardNumbers но я не знаю как его заменить на Arraylist так что бы я сам мог выставлять количество проявляемых MaterialCardView и мог менять в них текст. Как это сделать?

Я знаю что кода много, поэтому загрузил исходники в github https://github.com/Buldog18/Drag-and-drop

В Styles

style name="AppTheme"parent="Theme.MaterialComponents.Light.DarkActionBar"

CardAdapter

public class CardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    public int[] cardNumbers;

    private ItemTouchHelper itemTouchHelper;

    CardAdapter(int[] cardNumbers) {
        this.cardNumbers = cardNumbers;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.fragment_card, parent, /* attachToRoot= */ false);
        return new CardViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
        ((CardViewHolder) viewHolder).bind(cardNumbers[position], itemTouchHelper);
    }

    @Override
    public int getItemCount() {
        return cardNumbers.length;
    }

    void setItemTouchHelper(ItemTouchHelper itemTouchHelper) {
        this.itemTouchHelper = itemTouchHelper;
    }

    private static class CardViewHolder extends RecyclerView.ViewHolder {

        private final TextView titleView;
        private final View dragHandleView;

        private CardViewHolder(View itemView) {
            super(itemView);
            titleView = itemView.findViewById(R.id.card_txt);
            dragHandleView = itemView.findViewById(R.id.card_img);
        }

        @SuppressLint("ClickableViewAccessibility")
        private void bind(int cardNumber, final ItemTouchHelper itemTouchHelper) {
            titleView.setText(String.format(Locale.getDefault(), "Card #%02d", cardNumber));
            dragHandleView.setOnTouchListener(
                    (v, event) -> {
                        if (event.getAction() == MotionEvent.ACTION_DOWN) {
                            itemTouchHelper.startDrag(CardViewHolder.this);
                            return true;
                        }
                        return false;
                    });
        }
    }
}

CardItemTouchHelperCallback

public class CardItemTouchHelperCallback extends ItemTouchHelper.Callback {

    private static final int DRAG_FLAGS = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
    private static final int SWIPE_FLAGS = 0;

    private final CardAdapter cardAdapter;

    @Nullable
    private MaterialCardView dragCardView;

    CardItemTouchHelperCallback(CardAdapter cardAdapter) {
        this.cardAdapter = cardAdapter;
    }

    @Override
    public int getMovementFlags(
            @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        return makeMovementFlags(DRAG_FLAGS, SWIPE_FLAGS);
    }

    @Override
    public boolean onMove(
            @NonNull RecyclerView recyclerView,
            @NonNull RecyclerView.ViewHolder viewHolder,
            @NonNull RecyclerView.ViewHolder target) {
        int fromPosition = viewHolder.getAdapterPosition();
        int toPosition = target.getAdapterPosition();

        swapCards(fromPosition, toPosition, cardAdapter);
        return true;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
    }

    @Override
    public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
        super.onSelectedChanged(viewHolder, actionState);

        if (actionState == ItemTouchHelper.ACTION_STATE_DRAG && viewHolder != null) {
            dragCardView = (MaterialCardView) viewHolder.itemView;
            dragCardView.setDragged(true);
        } else if (actionState == ItemTouchHelper.ACTION_STATE_IDLE && dragCardView != null) {
            dragCardView.setDragged(false);
            dragCardView = null;
        }
    }

    static void swapCards(int fromPosition, int toPosition, CardAdapter cardAdapter) {
        int fromNumber = cardAdapter.cardNumbers[fromPosition];
        cardAdapter.cardNumbers[fromPosition] = cardAdapter.cardNumbers[toPosition];
        cardAdapter.cardNumbers[toPosition] = fromNumber;
        cardAdapter.notifyItemMoved(fromPosition, toPosition);
    }
}

NotificationsFragment

public class NotificationsFragment extends Fragment {

    public static NotificationsFragment newInstance() {
        return new NotificationsFragment();
    }
    private static final int CARD_COUNT = 30;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_notifications, container, false);
    }

    @Override
    public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) {
        RecyclerView recyclerView = view.findViewById(R.id.card_recy);

        CardAdapter cardAdapter = new CardAdapter(generateCardNumbers());
        ItemTouchHelper itemTouchHelper =
                new ItemTouchHelper(new CardItemTouchHelperCallback(cardAdapter));
        // Provide an ItemTouchHelper to the Adapter; can't use constructor due to circular dependency.
        cardAdapter.setItemTouchHelper(itemTouchHelper);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(cardAdapter);
        recyclerView
                .setAccessibilityDelegateCompat(new RecyclerViewAccessibilityDelegate(recyclerView) {
                    @NonNull
                    @Override
                    public AccessibilityDelegateCompat getItemDelegate() {
                        return new ItemDelegate(this) {

                            @Override
                            public void onInitializeAccessibilityNodeInfo(View host,
                                                                          AccessibilityNodeInfoCompat info) {
                                super.onInitializeAccessibilityNodeInfo(host, info);
                                int position = recyclerView.getChildLayoutPosition(host);
                                if (position != 0) {
                                    info.addAction(new AccessibilityNodeInfoCompat.AccessibilityActionCompat(R.id.move_card_up_action,
                                            host.getResources().getString(R.string.cat_card_action_move_up)));
                                }
                                if (position != (CARD_COUNT - 1)) {
                                    info.addAction(new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
                                            R.id.move_card_down_action,
                                            host.getResources().getString(R.string.cat_card_action_move_down)));
                                }
                            }

                            @Override
                            public boolean performAccessibilityAction(View host, int action, Bundle args) {
                                int fromPosition = recyclerView.getChildLayoutPosition(host);
                                if (action == R.id.move_card_down_action) {
                                    swapCards(fromPosition, fromPosition + 1, cardAdapter);
                                    return true;
                                } else if (action == R.id.move_card_up_action) {
                                    swapCards(fromPosition, fromPosition - 1, cardAdapter);
                                    return true;
                                }

                                return super.performAccessibilityAction(host, action, args);
                            }
                        };
                    }
                });
        itemTouchHelper.attachToRecyclerView(recyclerView);
    }

    private static int[] generateCardNumbers() {
        int[] cardNumbers = new int[CARD_COUNT];
        for (int i = 0; i < CARD_COUNT; i++) {
            cardNumbers[i] = i + 1;
        }
        return cardNumbers;
    }

}

fragment_card

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cat_card_list_item_card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="16dp"
    android:layout_marginTop="8dp"
    android:layout_marginRight="16dp"
    android:layout_marginBottom="8dp"
    android:clickable="true"
    android:focusable="true"
    android:minHeight="118dp">

    <TextView
        android:id="@+id/card_txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginRight="16dp"
        android:textAppearance="?attr/textAppearanceHeadline6"/>

    <ImageView
        android:id="@+id/card_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end"
        android:padding="16dp"
        android:src="@drawable/ic_quick_menu"
        tools:targetApi="jelly_bean"/>
</com.google.android.material.card.MaterialCardView>

fragment_notifications

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/card_recy"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </androidx.recyclerview.widget.RecyclerView>
</LinearLayout>

Ответы (0 шт):