Mobile Development 9 min read

Implementing a Multi‑Type RecyclerView Adapter with Drag‑And‑Drop and Scale Features on Android

This article demonstrates how to implement a multi-type RecyclerView adapter on Android that supports cross‑RecyclerView item dragging, scaling, and custom drag controls, providing code examples, interface definitions, and a step‑by‑step explanation of the underlying processes.

Qunar Tech Salon
Qunar Tech Salon
Qunar Tech Salon
Implementing a Multi‑Type RecyclerView Adapter with Drag‑And‑Drop and Scale Features on Android

Wei Zixiang, a developer at Qunar.com since 2017, introduces a library called MultiItem that helps build a multi‑type RecyclerView adapter for Android. The article focuses on implementing cross‑RecyclerView item dragging with optional scaling, a feature often needed in office‑style panel applications.

Effect Screenshots

Usage

Drag Functionality

Dragging is handled through an ItemDragHelper that forwards touch events to a listener ( ItemDragListener ). The helper is instantiated, a listener is set, and dispatchTouchEvent calls dragHelper.onTouch(ev) to consume the event when appropriate.

@Override
protected void onCreate(Bundle savedInstanceState){ ... }
// ItemDragHelper needs the outer horizontal RecyclerView
dragHelper = new ItemDragHelper(horizontalRecycler);
dragHelper.setOnItemDragListener(new OnBaseDragListener());
@Override
public boolean dispatchTouchEvent(MotionEvent ev){
    return dragHelper.onTouch(ev) || super.dispatchTouchEvent(ev);
}

For a vertical list, the data source must implement the ItemData interface and be registered with the adapter:

baseItemAdapter.register(TextDragBean.class, new TextViewDragManager());

To start a drag operation:

dragHelper.startDrag(viewHolder);

General Item Drag Control

The data source should also implement the ItemDrag interface, which defines three boolean methods that control whether an item can move within its own RecyclerView, switch to another RecyclerView, or be dragged at all.

public interface ItemDrag {
    /** Whether the item can be moved inside its own RecyclerView */
    boolean isCanMove();
    /** Whether the item can be transferred to another RecyclerView */
    boolean isCanChangeRecycler();
    /** Whether dragging is allowed */
    boolean isCanDrag();
}

Double‑Tap Zoom Functionality

A ViewScaleHelper is used to manage scaling of the outer content view and the horizontal RecyclerView. The helper can be toggled on or off, and the current scale can be queried from the drag listener.

// Instantiate the scale helper
scaleHelper = new ViewScaleHelper();
// Set the root content view
scaleHelper.setContentView(contentView);
// Set the horizontal RecyclerView
scaleHelper.setHorizontalView(horizontalRecycler);
// Add the vertical view for unified scaling
scaleHelper.addVerticalView(verticalView);
// Toggle scaling mode
scaleHelper.toggleScaleModel(); // or startScaleModel() / stopScaleModel()

Other Customizations

Custom business logic can be added by overriding methods in ItemDragListener . Examples include retrieving the current scale via getScale() , controlling item selection and movement, adjusting maximum scroll speeds, defining scroll limits, handling floating‑view drawing, and setting move boundaries.

Main Process Analysis

Generating the Floating View

The dragged item view is made invisible and a floating view is created using WindowManager + ImageView that displays a bitmap of the original item.

Calculating Horizontal and Vertical Scrolling

The implementation heavily references ItemTouchHelper . It calculates whether scrolling is needed based on the touch position, determines direction and distance, and uses a periodic Runnable to keep scrolling smoothly.

Item Position Swapping

When the touch point is over a horizontal RecyclerView, findChildViewUnder locates the target position. If the item needs to move to another RecyclerView, it is removed from the source and added to the destination. Subsequent calls to findChildViewUnder on the vertical RecyclerView determine whether the item view itself should be repositioned.

View Scaling

Scaling enlarges the outer container and the horizontal list by applying setScaleX and setScaleY . The scaled width is stored to avoid layout issues, and the original scale is restored when scaling stops.

Conclusion

The feature was implemented quickly as a beta version without extensive polishing. The article provides usage instructions and a brief flow analysis; readers are encouraged to explore the source code for deeper understanding and to suggest improvements.

AndroidRecyclerViewDragAndDropItemTouchHelperMultiTypeAdapterscale
Qunar Tech Salon
Written by

Qunar Tech Salon

Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.