react-native-table-component冻结可滚动表的第一列和第一行

时间:2019-02-27 22:55:31

标签: javascript android ios react-native

期望状态

我正在使用react-native-table-component,这是在React Native中渲染表的基本组件。我需要冻结表中的第一列和第一行,以便在滚动时仍可看到它们。具体来说,我需要第一列在水平滚动时保持固定,而在垂直滚动时与行中的其余数据一起滚动。

我需要第一行以相同的方式运行。垂直滚动和水平滚动时保持固定,我应该与相应的列一起滚动。

问题

对于第一行,我可以达到自己的状态,但是对于同一张表中的第一列,我不能做同样的事情。

代码

render(){
    return(

    <View style={styles.tableContainer}>
    <ScrollView horizontal={true}>
     <View>
       <Table style={styles.tableHead}>

         <Row
          style={styles.header}
          textStyle={styles.text}
          data={this.props.tableHead}
          widthArr={this.props.columnWidth}
        />

       </Table>
       <ScrollView style={styles.dataWrapper}>

        <TableWrapper style={styles.tableBody}>
          <Col 
            style={styles.title} 
            textStyle={styles.text}
            data={this.props.tableTitle} 
            heightArr={[28,28]}  
        />
          <Rows 
            style={styles.row} 
            textStyle={styles.text}
            data={this.dataFormat()} 
            widthArr={this.props.columnWidth} 

            />
        </TableWrapper>
       </ScrollView>
     </View>
   </ScrollView>
  </View>
    )
}

其他信息 我不需要使用react-native-table-component,但我想尽可能地使用它,因为我已经做了很多工作来设置它的样式和格式化我插入的数据。

在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

这是一个有效的解决方案。基本上,您需要将左窗格上的垂直滚动与第一列窗格同步。

// TableDemo.tsx

import React, { useRef } from 'react';
import { ScrollView, StyleSheet, View } from 'react-native';
import {
  Table,
  Row,
  Rows,
  Col,
} from 'react-native-table-component';

const borderColor = '#C1C0B9';
const primaryColor = 'dodgerblue';
const backgroundColor = '#F7F6E7';

export default function TableDemo() {
  const leftRef = useRef<ScrollView>(null);
  const rightRef = useRef<ScrollView>(null);

  const state = {
    tableHead: [
      'Head1',
      'Head2',
      'Head3',
      'Head4',
      'Head5',
      'Head6',
      'Head7',
      'Head8',
      'Head9',
    ],
    widthArr: [50, 60, 80, 100, 120, 140, 160, 180, 200],
  };

  const headerHeight = 40;
  const leftColumnWidth = 100;

  const recordData = [];
  for (let i = 0; i < 60; i += 1) {
    const rowData = [];
    rowData.push(`Record ${i}`);
    recordData.push(rowData);
  }

  const tableData = [];
  for (let i = 0; i < 60; i += 1) {
    const rowData = [];
    for (let j = 0; j < 9; j += 1) {
      rowData.push(`${i}${j}`);
    }
    tableData.push(rowData);
  }

  return (
    <View
      style={{
        flex: 1,
        flexDirection: 'row',
        backgroundColor: '#eee',
      }}
    >
      {/* Left Column */}
      <View
        style={{
          width: leftColumnWidth,
          backgroundColor: 'yellow',
          borderRightWidth: 1,
          borderRightColor: borderColor,
        }}
      >
        {/* Blank Cell */}
        <View
          style={{
            height: headerHeight,
            backgroundColor: primaryColor,
            borderBottomWidth: 1,
            borderBottomColor: borderColor,
          }}
        ></View>
        {/* Left Container : scroll synced */}
        <ScrollView
          ref={leftRef}
          style={{
            flex: 1,
            backgroundColor: 'white',
          }}
          scrollEnabled={false}
          showsVerticalScrollIndicator={false}
        >
          <Table
            borderStyle={{
              borderWidth: 1,
              borderColor,
            }}
          >
            {recordData.map((rowData, index) => (
              <Row
                key={index}
                data={rowData}
                widthArr={[leftColumnWidth]}
                style={index % 2 ? styles.row : { backgroundColor }}
                textStyle={styles.text}
              />
            ))}
          </Table>
        </ScrollView>
      </View>
      {/* Right Column */}
      <View
        style={{
          flex: 1,
          backgroundColor: 'white',
        }}
      >
        <ScrollView horizontal={true} bounces={false}>
          <View>
            <Table borderStyle={{ borderWidth: 1, borderColor }}>
              <Row
                data={state.tableHead}
                widthArr={state.widthArr}
                style={styles.head}
                textStyle={{ ...styles.text, color: 'white' }}
              />
            </Table>
            <ScrollView
              ref={rightRef}
              style={styles.dataWrapper}
              scrollEventThrottle={16}
              bounces={false}
              onScroll={(e) => {
                const { y } = e.nativeEvent.contentOffset;
                leftRef.current?.scrollTo({ y, animated: false });
              }}
            >
              <Table borderStyle={{ borderWidth: 1, borderColor }}>
                {tableData.map((rowData, index) => (
                  <Row
                    key={index}
                    data={rowData}
                    widthArr={state.widthArr}
                    style={index % 2 ? styles.row : { backgroundColor }}
                    textStyle={styles.text}
                  />
                ))}
              </Table>
            </ScrollView>
          </View>
        </ScrollView>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 16, paddingTop: 30, backgroundColor: '#eee' },
  head: { height: 40, backgroundColor: primaryColor },
  wrapper: { flexDirection: 'row' },
  title: { flex: 1, backgroundColor: '#f6f8fa' },
  row: { height: 28 },
  text: { textAlign: 'center' },
  dataWrapper: { marginTop: -1 },
});