react-native 中包含可折叠部分 header 的部分列表

Section list with collapsible section header in react-native

我正在使用 react-native 版本 0.61.5。我想在 react-native 中创建一个带有可折叠 header 的部分列表,如下图所示。

这是我的 API 数据格式

data:[
  {
    shift_name:'Day',
    data:[
    {
      id:'1',
      fullname: "seela",
      inspection_date: "2020-06-10T04:45:32Z",
      issues: 1,
      response:{
        shift_name:'Day'
      }
     }
    ]
  },
  {
    shift_name:'Afternoon',
    data:[
      {
        id:'2',
        fullname: "Raju vijayan",
        inspection_date: "2020-06-9T04:45:32Z",
        issues: 3,
        response:{
          shift_name:'Afternoon'
        }
      },
      {
        id:'3',
        fullname: "Pratap P",
        inspection_date: "2020-06-8T04:45:32Z",
        issues: 2,
        response:{
          shift_name:'Afternoon'
        }
      }
    ]
  }
]

当我单击 header 时,内容应该会展开和折叠。我怎样才能在 react-native 中做到这一点?

我假设你的数据是以状态存储的,对吧?所以我有一种方法是在每个名为 isCollapsed 的数据中添加一个额外的 属性 ,初始值为 true

单击某个项目的 header 时,您将该项目的 isCollapsed 设置为相反的值。

那么每个项目的可折叠视图的可见性状态取决于isCollapse 属性。

那是我的解决办法:)希望对你有帮助:)

请检查我的代码:

renderItem = (item, index) => {
      return (
          <View>
              // Header content
              <TouchableOpacity
                  onPress={() => {
                      let { data } = this.state;
                      data = data.map((item, key) => {
                          if (key === index) {
                              item.isCollapsed = !item.isCollapsed;
                          }
                          return item;
                      });
                      this.setState({
                          data,
                      });
                  }}
              >
              </TouchableOpacity>

              // Collapsible content
              <View style={{
                  display: (item.isCollapsed) ? 'flex' : 'none'
              }}>

              </View>
          </View>
      );
  }

使每个项目成为一个组件。

根据您的要求使用Layoutanimation

使用状态来管理项目的状态。即,打开和关闭。

const [open, setopen] = useState(false);

最初,项目处于关闭状态。

根据条件显示数据

逻辑:仅当项目关闭时才需要指定高度。

!open && { height: 40 }

如果没打开,给个header高度。否则,它会占用它需要的高度。

完整代码

import React, { useState } from 'react';
import {
  View, Text, StyleSheet, TouchableOpacity, LayoutAnimation, Platform, UIManager,
} from 'react-native';

if (Platform.OS === 'android') {
  if (UIManager.setLayoutAnimationEnabledExperimental) {
    UIManager.setLayoutAnimationEnabledExperimental(true);
  }
}


export default function TestFile() {
  return (
    <View style={styles.container}>
      <Item />
      <Item />
      <Item />
      <Item />
      <Item />
      <Item />
    </View>
  );
}


function Item() {
  const [open, setopen] = useState(false);
  const onPress = () => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
    setopen(!open);
  };
  return (
    <TouchableOpacity style={[styles.item, !open && { height: 40 }]} onPress={onPress} activeOpacity={1}>
      <Text>Header</Text>
      {open && (
        <View>
          <Text> SOME DATA</Text>
          <Text> SOME DATA</Text>
          <Text> SOME DATA</Text>
          <Text> SOME DATA</Text>
          <Text> SOME DATA</Text>
          <Text> SOME DATA</Text>
        </View>
      )}
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    padding: 50,
  },
  item: {
    width: '100%',
    borderWidth: 1,
    paddingHorizontal: 20,
    overflow: 'hidden',
    paddingVertical: 10,
    marginBottom: 5,
  },
});

结果