10-7 选中类别的拖拽排序

32 阅读1分钟

在本节中,我们将学习如何在分类模块中添加拖拽功能。以下是实现步骤:

使用拖拽排序库

pages/Category/index.tsx 中,使用 DragSortableView 组件实现拖拽排序功能:

import { DragSortableView } from 'react-native-drag-sort';

interface IProps extends ModelState {
  navigation: RootStackNavigation;
}

interface IState {
  myCategorys: ICategory[];
  classifyGroup: any;
}

class Category extends Component<IProps, IState> {
  state = {
    myCategorys: this.props.myCategorys,
    classifyGroup: {},
  };

  componentDidMount() {
    const { categorys } = this.props;
    const classifyGroup = _.groupBy(categorys, 'classify');
    this.setState({ classifyGroup });
  }

  onDataChange = (data: ICategory[]) => {
    this.setState({
      myCategorys: data,
    });
  };

  onClickItem = (data: ICategory[], item: ICategory) => {
    this.onPress(item, true);
  };

  render() {
    const { isEdit, categorys } = this.props;
    const { myCategorys, classifyGroup } = this.state;

    return (
      <DragSortableView
        dataSource={myCategorys}
        fixedItems={[0, 1]} // 固定的类别
        sortable={isEdit} // 是否开启拖拽
        onClickItem={this.onClickItem}
        onDataChange={this.onDataChange}
        keyExtractor={(item) => item.id}
        renderItem={({ item, index }) => (
          <Item
            data={item}
            isEdit={isEdit}
            selected
            onPress={() => this.onPress(item, true)}
            onLongPress={() => this.onLongPress(index)}
            fixedItems={[0, 1]}
            index={index}
          />
        )}
      />
    );
  }
}

更新 Item 组件

pages/Category/Item.tsx 中,根据拖拽状态调整样式:

interface IProps {
  data: ICategory;
  isEdit: boolean;
  selected: boolean;
  onPress: () => void;
  onLongPress: () => void;
  fixedItems: number[];
  index: number;
}

class Item extends React.Component<IProps> {
  render() {
    const { data, isEdit, selected, onPress, onLongPress, fixedItems, index } = this.props;
    const WrapperComponent = selected ? View : Touchable;
    const fixed = fixedItems.includes(index);

    return (
      <WrapperComponent
        key={data.id}
        style={styles.itemWrapper}
        onPress={onPress}
        onLongPress={onLongPress}
      >
        <View
          style={StyleSheet.flatten([
            styles.item,
            isEdit && fixed ? styles.fixed : undefined,
          ])}
        >
          <Text style={styles.text}>{data.name}</Text>
          {isEdit && (
            <View style={styles.icon}>
              <Text style={styles.iconText}>{selected ? '-' : '+'}</Text>
            </View>
          )}
        </View>
      </WrapperComponent>
    );
  }
}

const styles = StyleSheet.create({
  fixed: {
    opacity: 0.5,
  },
});

适配设备平台

navigator/index.tsx 中适配设备平台:

<Stack.Navigator
  headerMode="float"
  screenOptions={{
    headerTintColor: '#333',
    headerBackTitleVisible: false,
    ...Platform.select({
      android: {
        headerStatusBarHeight: StatusBar.currentHeight,
      },
    }),
  }}
/>

总结

在本节中,我们实现了分类模块的拖拽功能。通过使用 react-native-drag-sort 库,用户可以方便地拖拽和排序已选择的类别。下一节,我们将学习如何根据选择的类别动态渲染顶部标签以及动态夹杂 Dva 的 Model。