React Native 底部高度固定的可滚动列表项

d4so4syb  于 2023-04-22  发布在  React
关注(0)|答案(1)|浏览(161)

我使用了库“@戈勒姆/bottom-sheet”来创建一个底部工作表。下面是代码供您参考:

import React, { useCallback, useMemo, useRef, useState } from 'react';
import { View, Text, StyleSheet, FlatList, TouchableOpacity, LayoutAnimation } from 'react-native';
import BottomSheet from '@gorhom/bottom-sheet';
import UpArrowIcon from "../../../../assets/img/icons/bottom_sheet_up_arrow.svg"
import DownArrowIcon from "../../../../assets/img/icons/bottom_sheet_down_arrow.svg"
import RightArrowIcon from "../../../../assets/img/icons/bottom_sheet_right_arrow.svg"
import CloseIcon from "../../../../assets/img/icons/bottom_sheet_close_icon.svg"

const App = () => {
  // ref
  const bottomSheetRef = useRef<BottomSheet>(null);

  const [expandedItem, setExpandedItem] = useState(null);

  // variables
  const snapPoints = useMemo(() => ['25%', '50%'], []);

  // callbacks
  const handleSheetChanges = useCallback((index: number) => {
    console.log('handleSheetChanges', index);
  }, []);

  const data = [
    { label: '2D Test' },
    { label: '2D Testing 2' },
    { label: '2D Testing 3' },
    { label: '2D Testing 1' },
    { label: '2D Testzaffar' },
    { label: '2D TestZaffar' },
  ];

  const expandedData = [
    { label: 'Dashboard' },
    { label: 'List of Subspaces' },
    { label: 'View Space Details' },
    { label: 'Create Subspace' },
  ];

  const renderItem = ({ item, index }) => {
    const isExpanded = expandedItem === index;

    const handlePress = () => {
      LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
      setExpandedItem(isExpanded ? null : index);
    };

    return (
      <View style={styles.itemContainer}>
        <TouchableOpacity onPress={handlePress}>
          <View style={styles.labelContainer}>
            <Text style={styles.label}>{item.label}</Text>
            {isExpanded ? (
              <UpArrowIcon width={12} height={10} style={styles.arrowIcon} />
            ) : (
              <DownArrowIcon width={12} height={10} style={styles.arrowIcon} />
            )}
          </View>
        </TouchableOpacity>
        {isExpanded && (
          <FlatList
            data={expandedData}
            renderItem={({ item }) => (
              <>
                <TouchableOpacity style={styles.rowContainer}>
                  <View style={styles.row}>
                    <Text style={styles.rowLabel}>{item.label}</Text>
                    <RightArrowIcon style={styles.rowArrowIcon} />
                  </View>
                </TouchableOpacity>
                {item.label === 'List of Subspaces' && <View style={styles.separator} />}
              </>
            )}
            keyExtractor={(item) => item.label}
          />
        )}
      </View>
    );
  };

  // renders
  return (
    <View style={styles.container}>
      <BottomSheet
        ref={bottomSheetRef}
        index={1}
        snapPoints={snapPoints}
        onChange={handleSheetChanges}
      >
        <View style={styles.bottomSheet}>
          <TouchableOpacity onPress={() => handleSheetChanges} style={styles.closeIcon}>
            <CloseIcon width={14.65} height={14.65} />
          </TouchableOpacity>
          <View style={styles.header}>
            <Text style={styles.title}>Truminds</Text>
            <Text style={[styles.create, { color: expandedItem !== null ? '#0F8D48' : '#4D4D4D' }]}>
              + Create Subspace
            </Text>
          </View>
          <View style={styles.separator} />
          <FlatList
            style={styles.list}
            data={data}
            renderItem={renderItem}
            keyExtractor={(item) => item.label}
          />
        </View>
      </BottomSheet>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingHorizontal: 0,
    paddingTop: 28,
    paddingBottom: 12,
  },
  itemContainer: {
    backgroundColor: '#F2F2F2',
    padding: 10,
    borderRadius: 10,
    marginBottom: 17,
  },
  title: {
    fontSize: 24,
    fontWeight: '800',
    color: '#4D4D4D',
    //fontFamily: fontFamily.theme.EXTRA_BOLD
  },
  create: {
    fontSize: 12,
    fontWeight: '600',
  },
  bottomSheet: {
    backgroundColor: 'white',
    borderTopLeftRadius: 20,
    borderTopRightRadius: 20,
    paddingHorizontal: 5,
    paddingBottom: 10,
    marginTop: -20,
  },
  separator: {
    height: 1,
    backgroundColor: '#ddd',
    marginVertical: 10,
  },
  list: {
    marginTop: 10,
  },
  listItem: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingVertical: 10,
  },
  labelContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingBottom: 3,
    paddingTop: 3,
  },
  label: {
    fontSize: 16,
    fontWeight: '600',
    color: '#4D4D4D',
  },
  arrowIcon: {
    marginLeft: 10,
    color: '#000000',
  },
  closeIcon: {
    flex: 1,
    alignItems: 'flex-end',
  },
  rowContainer: {
    paddingHorizontal: 4,
    paddingVertical: 10,
  },
  row: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  rowLabel: {
    fontSize: 12,
    fontWeight: '500',
    color: '#4D4D4D',
  },
  rowArrowIcon: {
    marginLeft: 10,
    color: '#000000',
  },
});

export default App;

我注意到在最下面的工作表中并不是数据数组的所有列表项都是可见的。
我不得不增加底部工作表的高度来查看所有列表项。我想要的是,我应该能够滚动所有列表项,而不管底部工作表的高度如何。由于意外的滚动行为,将flatlist Package 在scrollView周围似乎不正确。我还能做什么?

s3fp2yjn

s3fp2yjn1#

如果我没记错的话,有一次我通过在组件上设置maxHeight解决了一个类似的问题。你需要从React Native导入Dimensions模块来尝试这种方法。希望这能帮助你。

const maxHeight = useMemo(() => Dimensions.get('window').height * 0.9, []);
<BottomSheet
 ref={bottomSheetRef}
 index={1}
 snapPoints={snapPoints}
 maxHeight={maxHeight}
 onChange={handleSheetChanges}
>

相关问题