【问题标题】:FlatList Sticky header does not work inside ScrollView?FlatList Sticky 标头在 ScrollView 中不起作用?
【发布时间】:2018-11-04 11:11:48
【问题描述】:

React 本机 FlatList 粘性标头在没有 ScrollView 的情况下也能正常工作。但是当我添加Parallax ScrollView(甚至是简单的ScrollView)时,FlatList 的粘性标题不起作用。 (带有滚动视图的粘性标题滚动。) 自 1 天以来,我一直陷入这个问题。

首先我想要Parallax ScrollView,当Parallax ScrollView 不起作用时,我尝试了简单的ScrollView。

我已经尝试了 5 个 Parallax scrollView,例如 thisthis。但没有一个奏效。

如果使用 FlatList 粘性标头无法实现 Parallax ScrollView,那么至少告诉 一些技巧将 FlatList 放入简单的滚动视图中,这适用于 Android 和 iOS 。这是我的带有滚动视图和 FlatList 的代码。

import { Body, Left, ListItem, Right, Text, View } from "native-base";
import React from "react";
import { FlatList, ScrollView } from "react-native";
var _this;
export default class App extends React.Component {
  constructor() {
    super();
    _this = this;
    this.state = {
      data: [
        { name: "Movies", header: true },
        { name: "Interstellar", header: false },
        { name: "Dark Knight", header: false },
        { name: "Pop", header: false },
        { name: "Pulp Fiction", header: false },
        { name: "Burning Train", header: false },
        { name: "Music", header: true },
        { name: "Adams", header: false },
        { name: "Nirvana", header: false },
        { name: "Amrit Maan", header: false },
        { name: "Oye Hoye", header: false },
        { name: "Eminem", header: false },
        { name: "Places", header: true },
        { name: "Jordan", header: false },
        { name: "Punjab", header: false },
        { name: "Ludhiana", header: false },
        { name: "Jamshedpur", header: false },
        { name: "India", header: false },
        { name: "People", header: true },
        { name: "Jazzy", header: false },
        { name: "Appie", header: false },
        { name: "Baby", header: false },
        { name: "Sunil", header: false },
        { name: "Arrow", header: false },
        { name: "Things", header: true },
        { name: "table", header: false },
        { name: "chair", header: false },
        { name: "fan", header: false },
        { name: "cup", header: false },
        { name: "cube", header: false }
      ],
      stickyHeaderIndices: []
    };
  }
  componentDidMount() {
    var arr = [];
    this.state.data.map(obj => {
      if (obj.header) {
        arr.push(this.state.data.indexOf(obj));
      }
    });
    arr.push(0);
    this.setState({
      stickyHeaderIndices: arr
    });
  }

  renderItem = ({ item }) => {
    if (item.header) {
      return (
        <ListItem itemDivider>
          <Left />
          <Body style={{ marginRight: 40 }}>
            <Text style={{ fontWeight: "bold" }}>{item.name}</Text>
          </Body>
          <Right />
        </ListItem>
      );
    } else if (!item.header) {
      return (
        <ListItem style={{ marginLeft: 0 }}>
          <Body>
            <Text>{item.name}</Text>
          </Body>
        </ListItem>
      );
    }
  };

  showCartScreen() {
    _this.props.navigation.navigate("ScreenCart");
  }

  render() {
    return (
      <ScrollView style={{ flex: 1 }}>
        <View style={{height : 200}}></View>
        <FlatList
          data={this.state.data}
          renderItem={this.renderItem}
          keyExtractor={item => item.name}
          stickyHeaderIndices={this.state.stickyHeaderIndices}
        />
      </ScrollView>
    );
  }
}

具有视差滚动视图的代码,其中平面列表不能完全滚动。

import { FlatList } from "react-native";
import { Text, ListItem, Left, Body, Icon, Right, Title } from "native-base";
import React, { Component } from "react";
import {
  Dimensions,
  Image,
  ListView,
  PixelRatio,
  StyleSheet,
  View
} from "react-native";

import ParallaxScrollView from "react-native-parallax-scroll-view";
export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      data: [
        { name: "Movies", header: true },
        { name: "Interstellar", header: false },
        { name: "Dark Knight", header: false },
        { name: "Pop", header: false },
        { name: "Pulp Fiction", header: false },
        { name: "Burning Train", header: false },
        { name: "Music", header: true },
        { name: "Adams", header: false },
        { name: "Nirvana", header: false },
        { name: "Amrit Maan", header: false },
        { name: "Oye Hoye", header: false },
        { name: "Eminem", header: false },
        { name: "Places", header: true },
        { name: "Jordan", header: false },
        { name: "Punjab", header: false },
        { name: "Ludhiana", header: false },
        { name: "Jamshedpur", header: false },
        { name: "India", header: false },
        { name: "People", header: true },
        { name: "Jazzy", header: false },
        { name: "Appie", header: false },
        { name: "Baby", header: false },
        { name: "Sunil", header: false },
        { name: "Arrow", header: false },
        { name: "Things", header: true },
        { name: "table", header: false },
        { name: "chair", header: false },
        { name: "fan", header: false },
        { name: "cup", header: false },
        { name: "cube", header: false }
      ],
      stickyHeaderIndices: [],
      dataSource: new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2
      }).cloneWithRows([
        "Simplicity Matters",
        "Hammock Driven Development",
        "Value of Values",
        "Are We There Yet?",
        "The Language of the System",
        "Design, Composition, and Performance",
        "Clojure core.async",
        "The Functional Database",
        "Deconstructing the Database",
        "Hammock Driven Development",
        "Value of Values"
      ])
    };
  }
  componentDidMount() {
    var arr = [];
    this.state.data.map(obj => {
      if (obj.header) {
        arr.push(this.state.data.indexOf(obj));
      }
    });
    arr.push(0);
    this.setState({
      stickyHeaderIndices: arr
    });
  }

  renderItem = ({ item }) => {
    if (item.header) {
      return (
        <ListItem itemDivider>
          <Left />
          <Body style={{ marginRight: 40 }}>
            <Text style={{ fontWeight: "bold" }}>{item.name}</Text>
          </Body>
          <Right />
        </ListItem>
      );
    } else if (!item.header) {
      return (
        <ListItem style={{ marginLeft: 0 }}>
          <Body>
            <Text>{item.name}</Text>
          </Body>
        </ListItem>
      );
    }
  };
  // render() {
  //   return (
  //     <FlatList
  //       data={this.state.data}
  //       renderItem={this.renderItem}
  //       keyExtractor={item => item.name}
  //       stickyHeaderIndices={this.state.stickyHeaderIndices}
  //     />
  //   );
  // }

  render() {
    const { onScroll = () => {} } = this.props;
    return (
      <FlatList
        ref="ListView"
        style={styles.container}
        data={this.state.data}
        renderItem={this.renderItem}
        keyExtractor={item => item.name}
        stickyHeaderIndices={this.state.stickyHeaderIndices}
        renderScrollComponent={props => (
          <ParallaxScrollView
            onScroll={onScroll}
            headerBackgroundColor="#333"
            stickyHeaderHeight={STICKY_HEADER_HEIGHT}
            parallaxHeaderHeight={PARALLAX_HEADER_HEIGHT}
            backgroundSpeed={10}
            renderBackground={() => (
              <View key="background">
                <Image
                  source={{
                    uri: "https://i.ytimg.com/vi/P-NZei5ANaQ/maxresdefault.jpg",
                    width: window.width,
                    height: PARALLAX_HEADER_HEIGHT
                  }}
                />
                <View
                  style={{
                    position: "absolute",
                    top: 0,
                    width: window.width,
                    backgroundColor: "rgba(0,0,0,.4)",
                    height: PARALLAX_HEADER_HEIGHT
                  }}
                />
              </View>
            )}
            renderForeground={() => (
              <View key="parallax-header" style={styles.parallaxHeader}>
                <Image
                  style={styles.avatar}
                  source={{
                    uri:
                      "https://pbs.twimg.com/profile_images/2694242404/5b0619220a92d391534b0cd89bf5adc1_400x400.jpeg",
                    width: AVATAR_SIZE,
                    height: AVATAR_SIZE
                  }}
                />
                <Text style={styles.sectionSpeakerText}>
                  Talks by Rich Hickey
                </Text>
                <Text style={styles.sectionTitleText}>
                  CTO of Cognitec, Creator of Clojure
                </Text>
              </View>
            )}
            renderStickyHeader={() => (
              <View key="sticky-header" style={styles.stickySection}>
                <Text style={styles.stickySectionText}>Rich Hickey Talks</Text>
              </View>
            )}
            renderFixedHeader={() => (
              <View key="fixed-header" style={styles.fixedSection}>
                <Text
                  style={styles.fixedSectionText}
                  onPress={() => this.refs.ListView.scrollTo({ x: 0, y: 0 })}
                >
                  Scroll to top
                </Text>
              </View>
            )}
          />
        )}
      />
    );
  }
}


const window = Dimensions.get("window");

const AVATAR_SIZE = 120;
const ROW_HEIGHT = 60;
const PARALLAX_HEADER_HEIGHT = 350;
const STICKY_HEADER_HEIGHT = 70;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "black"
  },
  background: {
    position: "absolute",
    top: 0,
    left: 0,
    width: window.width,
    height: PARALLAX_HEADER_HEIGHT
  },
  stickySection: {
    height: STICKY_HEADER_HEIGHT,
    width: 300,
    justifyContent: "flex-end"
  },
  stickySectionText: {
    color: "white",
    fontSize: 20,
    margin: 10
  },
  fixedSection: {
    position: "absolute",
    bottom: 10,
    right: 10
  },
  fixedSectionText: {
    color: "#999",
    fontSize: 20
  },
  parallaxHeader: {
    alignItems: "center",
    flex: 1,
    flexDirection: "column",
    paddingTop: 100
  },
  avatar: {
    marginBottom: 10,
    borderRadius: AVATAR_SIZE / 2
  },
  sectionSpeakerText: {
    color: "white",
    fontSize: 24,
    paddingVertical: 5
  },
  sectionTitleText: {
    color: "white",
    fontSize: 18,
    paddingVertical: 5
  },
  row: {
    overflow: "hidden",
    paddingHorizontal: 10,
    height: ROW_HEIGHT,
    backgroundColor: "white",
    borderColor: "#ccc",
    borderBottomWidth: 1,
    justifyContent: "center"
  },
  rowText: {
    fontSize: 20
  }
});

【问题讨论】:

    标签: android ios reactjs react-native ecmascript-6


    【解决方案1】:

    在这段代码中,只需用“View”删除“ScrollView”就可以了

    <ScrollView style={{ flex: 1 }}>
      <View style={{height : 200}}></View>
      <FlatList data={this.state.data}
       renderItem={this.renderItem}
       keyExtractor={item => item.name}
       stickyHeaderIndices={this.state.stickyHeaderIndices} />
    </ScrollView>
    

    原因:平面列表具有默认滚动视图,并且您将其放在滚动视图中,因此滚动它不会将顶部位置固定到标题

    【讨论】:

    • 这可能吗,图像滚动和隐藏以及标题粘在屏幕顶部?我已经尝试过上面提到的视差滚动视图,也有同样的问题。
    • 是的,你可以在渲染中添加这些:" renderItem={({item}) => }"
    • renderItem={({item}) => {item.user_name} }跨度>
    • 我用这个替换了我的方法,但是编译时错误很多。
    • 我需要像上面一样在视差视图中带有标题的平面列表。
    猜你喜欢
    • 2020-09-25
    • 2021-05-24
    • 1970-01-01
    • 2016-11-03
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    相关资源
    最近更新 更多