Список разделов со сворачиваемым заголовком раздела в react-native

Я использую версию 0.61.5 с поддержкой реакции. Я хочу создать список разделов со сворачиваемым заголовком в react-native, как показано на изображении ниже.

Вот мой формат данных 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'
        }
      }
    ]
  }
]

введите описание изображения здесь

Когда я нажимаю на заголовок, содержимое должно разворачиваться и сворачиваться. Как это сделать в react-native?


person Pratap Penmetsa    schedule 12.06.2020    source источник


Ответы (2)


Сделайте каждый предмет компонентом.

Используйте Layoutanimation в соответствии с вашими требованиями.

Используйте состояние для управления состояниями элемента. т.е. открывать и закрывать.

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

Изначально элемент находится в закрытом состоянии.

Отображение данных в соответствии с условием.

Логика: указывать высоту нужно только в том случае, если предмет закрыт.

!open && { height: 40 }

если он не открыт, укажите высоту заголовка. В противном случае он займет нужную ему высоту.

Полный код

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,
  },
});

Результат

введите описание изображения здесь

person Aswin C    schedule 12.06.2020

Я предполагаю, что ваши данные хранятся в состоянии, верно? Итак, у меня есть подход, который добавляет дополнительное свойство в каждый из ваших данных с именем isCollapsed с начальным значением true

Когда щелкают заголовок элемента, вы устанавливаете 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>
      );
  }

person Brian H.    schedule 12.06.2020