android - FlatList Sticky header 在 ScrollView 中不起作用?

标签 android ios reactjs react-native ecmascript-6

React native FlatList 粘性 header 在没有 ScrollView 的情况下也能正常工作。但是当我添加一个 Parallax ScrollView(或者甚至是简单的 ScrollView)时,FlatList 的粘性标题不起作用。 (带有 ScrollView 的粘性标题滚动。) 我从 1 天起就陷入了这个问题。

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

我已经尝试过 5 个视差 ScrollView ,例如 thisthis .但都没有用。

如果 Parallax ScrollView 无法使用 FlatList 粘性 header ,那么至少告诉一些将 FlatList 放入简单 ScrollView 的技巧,这适用于 Android 和 iOS。这是我使用 scrollview 和 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>
    );
  }
}

带有视差 ScrollView 的代码,其中 Flat-list 不能完全滚动。

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

最佳答案

在此代码块中,只需删除带有“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>

原因:平面列表具有默认的 ScrollView ,而您将其置于 ScrollView 中,因此在滚动时它不会将顶部位置固定在标题上

关于android - FlatList Sticky header 在 ScrollView 中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50522647/

相关文章:

android - 在 Android 中使用 GridView 是否安全?

ios - 如何使用 SwiftUI Picker 更新 Realm 一对一关系?

javascript - 如何使用 React Native 在 Android 上使用与 ios 相同的自定义字体

Android Cling/Upnp proguard

android - 如何将可绘制的 xml 文件添加到使用 For 循环创建的单选按钮中

android - 如何在我们的应用程序中播放来自soundcloud的音频?

ios - 在 iOS 上嵌入 Mono

ios - IOS 应用程序中的 Facebook 登录对象不能为 nil

javascript - react : update one item in a list without recreating all items

javascript - 如何在获取请求中传递变量