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

Posted

技术标签:

【中文标题】react-native-table-component 冻结可滚动表中的第一列和第一行【英文标题】:react-native-table-component freeze first column & first row in scrollable table 【发布时间】:2019-02-27 22:55:31 【问题描述】:

理想状态

我正在使用 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 但如果可能的话我想使用它,因为我已经做了很多工作来设置它的样式并格式化我插入的数据。

提前感谢您的帮助!

【问题讨论】:

这正是我的问题,你有没有机会想出一个解决方案? 不,我还没有!我暂时推迟了它,但我肯定需要在接下来的几个月内解决它。我在网上阅读了有关使用两个滚动视图的信息,一个用于要修复的左列,另一个用于表的其余部分。然后,您将两者“链接”在一起,因此当滚动一个时,另一个也滚动。我还没有尝试过,但它可能是唯一的选择 你试过这个吗:build.affinity.co/…(他们在文章中也有一个零食的例子)。它涉及一个列表视图和一个平面列表(以及使滚动看起来平滑的动画),我今天要尝试并报告。 我建议尝试将您的表格放入我上面展示的模板中,它就像一个魅力(即使在我的情况下有 9 列和 170 多行) 【参考方案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 ,
);

【讨论】:

以上是关于react-native-table-component 冻结可滚动表中的第一列和第一行的主要内容,如果未能解决你的问题,请参考以下文章