Implementing a Scale Decorator in a Draggable FlatList in React Native

October 29, 2024

Creating a visually interactive and user-friendly experience is key in mobile app development. React Native’s FlatList is highly versatile and efficient, commonly used for rendering large lists. With the added benefit of drag-and-drop functionality, you can make your FlatList even more engaging. In this article, we’ll explore how to implement a draggable FlatList in React Native, complete with a scale decorator to make items pop and respond to touch.

Prerequisites

Before starting, ensure you have basic knowledge of React Native and some familiarity with animations in React Native. You’ll also need to install the following libraries:

  1. react-native-reanimated – for animations.
  2. react-native-gesture-handler – for handling touch gestures.
  3. react-native-draggable-flatlist – for draggable list functionality.
npm install react-native-reanimated react-native-gesture-handler react-native-draggable-flatlist
Step 1: Set Up Draggable FlatList

Begin by importing the necessary components and setting up a simple draggable FlatList.

import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import DraggableFlatList, { ScaleDecorator } from 'react-native-draggable-flatlist';

const data = Array.from({ length: 10 }, (v, i) => ({
    key: `item-${i}`,
    label: `Item ${i + 1}`,
}));

const DraggableList = () => {
    const [items, setItems] = React.useState(data);
    const renderItem = ({ item, drag, isActive }) => {
        return (
            <ScaleDecorator activeScale={1.1}>
                <View
                    style={[
                        styles.itemContainer,
                        { backgroundColor: isActive ? '#e0f7fa' : '#fafafa' },
                    ]}
                >
                    <Text style={styles.text} onLongPress={drag}>
                        {item.label}
                    </Text>
                </View>
            </ScaleDecorator>
        );
    };
    return (
        <DraggableFlatList
            data={items}
            onDragEnd={({ data }) => setItems(data)}
            keyExtractor={(item) => item.key}
            renderItem={renderItem}
        />
    );
};
export default DraggableList;

Here’s what’s happening:

  1. Data Array: We set up an array of items to render in the list.
  2. DraggableFlatList Component: This renders a list where items can be dragged.
  3. Render Item: Each item displays text and uses drag from the render prop to enable dragging on long-press.
  4. ScaleDecorator: Wraps each list item and provides a scaling effect when active.
Step 2: Apply the Scale Decorator

The ScaleDecorator from react-native-draggable-flatlist is a powerful tool for providing visual feedback on item selection. Setting activeScale controls the scale size when an item is being dragged.

<ScaleDecorator activeScale={1.1}>

In this example, setting activeScale={1.1} scales the item to 110% of its original size when active. Adjust the scale factor as needed for your UI.

Step 3: Add Custom Styles

Enhance the appearance and interaction by adding some custom styles.

const styles = StyleSheet.create({
  itemContainer: {
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
    borderRadius: 8,
    borderWidth: 1,
    borderColor: '#ddd',
  },
  text: {
    fontSize: 18,
    fontWeight: 'bold',
  },
});

These styles define padding, margin, and basic colors, giving each item a card-like appearance.

Step 4: Animations with react-native-reanimated (Optional)

If you’d like more control over scaling or want to animate other properties during dragging, consider integrating react-native-reanimated. Here’s a quick example of how to achieve a smooth scale-in and scale-out effect with Reanimated.

  1. Install Reanimated and import it.
  2. Wrap each item in an Animated.View, where the scale value changes based on dragging state.

import Animated, { useAnimatedStyle, withSpring } from ‘react-native-reanimated’;

const renderItem = ({ item, drag, isActive }) => {
  const scale = isActive ? withSpring(1.1) : withSpring(1);
  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale }],
  }));

  return (
    <Animated.View style={[styles.itemContainer, animatedStyle]}>
      <Text style={styles.text} onLongPress={drag}>
        {item.label}
      </Text>
    </Animated.View>
  );
};

Testing and Troubleshooting

Run the app on a device or emulator, and test the drag-and-drop functionality by pressing and holding an item, then moving it around.

Tips

  • Experiment with activeScale in ScaleDecorator for the ideal scale.
  • Adjust item padding and margin to create a layout that suits your design.
  • Use withSpring() in Reanimated for a smooth scale-in-out transition.

Conclusion

Adding a draggable FlatList with a scale decorator in React Native enhances user interaction by giving visual feedback and creating a seamless drag-and-drop experience. Whether for a to-do list, task manager, or even a reordering UI, the scale decorator makes the app feel polished and responsive.

By combining react-native-draggable-flatlist, ScaleDecorator, and optional Reanimated animations, you can create a dynamic and interactive list that stands out. Now, you’re ready to implement an engaging, drag-friendly list that users will love!

en_USEnglish