1

带滚动条的应用

在我绘制的图像中,您可以看到两个区域,黄色的区域是 ScrollView,红色的区域是平面列表。当我从红色区域滚动时,我希望选项卡向上移动到标题,一旦它们接触到标题,就开始滚动 FlatList 的红色区域。为此,当标签触摸标题时,我将黄色区域的 scrollEnabled 设置为 false,问题是红色区域不会滚动,直到我停止按下并再次按下。

我想要的行为类似于Instagram配置文件,其中有一些标签,然后是照片列表,当标签触摸标头时,您可以继续从图像滚动。

4

1 回答 1

0

我将添加一些选项

  1. 第一个是零食,它再次使用父子滚动视图 Collapsible Header Tabs Snack

问题:这在 Android 上存在问题。当父滚动视图和子滚动视图都在滚动时,android 上的滚动会卡住。

  1. 二是github repo React-Native-Collapsing-TabView

问题:如果其中一个选项卡被滚动并且您转到另一个选项卡,那么顶部会有空白。问题

  1. 使用原生基础。
import React, {Component} from "react";
import {Animated, Dimensions, Platform, Text, TouchableOpacity, View} from "react-native";
import {Body, Header, List, ListItem as Item, ScrollableTab, Tab, TabHeading, Tabs, Title} from "native-base";
import LinearGradient from "react-native-linear-gradient";

const {width: SCREEN_WIDTH} = Dimensions.get("window");
const IMAGE_HEIGHT = 250;
const HEADER_HEIGHT = Platform.OS === "ios" ? 64 : 50;
const SCROLL_HEIGHT = IMAGE_HEIGHT - HEADER_HEIGHT;
const THEME_COLOR = "rgba(85,186,255, 1)";
const FADED_THEME_COLOR = "rgba(85,186,255, 0.8)";

export default class ParallaxDemo extends Component {
  nScroll = new Animated.Value(0);
  scroll = new Animated.Value(0);
  textColor = this.scroll.interpolate({
    inputRange: [0, SCROLL_HEIGHT / 5, SCROLL_HEIGHT],
    outputRange: [THEME_COLOR, FADED_THEME_COLOR, "white"],
    extrapolate: "clamp"
  });
  tabBg = this.scroll.interpolate({
    inputRange: [0, SCROLL_HEIGHT],
    outputRange: ["white", THEME_COLOR],
    extrapolate: "clamp"
  });
  tabY = this.nScroll.interpolate({
    inputRange: [0, SCROLL_HEIGHT, SCROLL_HEIGHT + 1],
    outputRange: [0, 0, 1]
  });
  headerBg = this.scroll.interpolate({
    inputRange: [0, SCROLL_HEIGHT, SCROLL_HEIGHT + 1],
    outputRange: ["transparent", "transparent", THEME_COLOR],
    extrapolate: "clamp"
  });
  imgScale = this.nScroll.interpolate({
    inputRange: [-25, 0],
    outputRange: [1.1, 1],
    extrapolateRight: "clamp"
  });
  imgOpacity = this.nScroll.interpolate({
    inputRange: [0, SCROLL_HEIGHT],
    outputRange: [1, 0],
  });
  tabContent = (x, i) => <View style={{height: this.state.height}}>
    <List onLayout={({nativeEvent: {layout: {height}}}) => {
      this.heights[i] = height;
      if (this.state.activeTab === i) this.setState({height})
    }}>
      {new Array(x).fill(null).map((_, i) => <Item key={i}><Text>Item {i}</Text></Item>)}
    </List></View>;
  heights = [500, 500];
  state = {
    activeTab: 0,
    height: 500
  };

  constructor(props) {
    super(props);
    this.nScroll.addListener(Animated.event([{value: this.scroll}], {useNativeDriver: false}));
  }

  render() {
    return (
      <View>
        <Animated.View style={{position: "absolute", width: "100%", backgroundColor: this.headerBg, zIndex: 1}}>
          <Header style={{backgroundColor: "transparent"}} hasTabs>
            <Body>
            <Title>
              <Animated.Text style={{color: this.textColor, fontWeight: "bold"}}>
                Tab Parallax
              </Animated.Text>
            </Title>
            </Body>
          </Header>
        </Animated.View>
        <Animated.ScrollView
          scrollEventThrottle={5}
          showsVerticalScrollIndicator={false}
          onScroll={Animated.event([{nativeEvent: {contentOffset: {y: this.nScroll}}}], {useNativeDriver: true})}
          style={{zIndex: 0}}>
          <Animated.View style={{
            transform: [{translateY: Animated.multiply(this.nScroll, 0.65)}, {scale: this.imgScale}],
            backgroundColor: THEME_COLOR
          }}>
            <Animated.Image
              source={{uri: "https://upload.wikimedia.org/wikipedia/commons/c/c5/Moraine_Lake_17092005.jpg"}}
              style={{height: IMAGE_HEIGHT, width: "100%", opacity: this.imgOpacity}}>
              {/*gradient*/}
              {/* <LinearGradient
                colors={["rgba(255,255,255,0.9)", "rgba(255,255,255,0.35)", "rgba(255,255,255,0)"]}
                locations={[0, 0.25, 1]}
                style={{position: "absolute", height: "100%", width: "100%"}}/> */}
            </Animated.Image>
          </Animated.View>
          <Tabs
            prerenderingSiblingsNumber={3}
            onChangeTab={({i}) => {
              this.setState({height: this.heights[i], activeTab: i})
            }}
            renderTabBar={(props) => <Animated.View
              style={{transform: [{translateY: this.tabY}], zIndex: 1, width: "100%", backgroundColor: "white"}}>
              <ScrollableTab {...props}
                             renderTab={(name, page, active, onPress, onLayout) => (
                               <TouchableOpacity key={page}
                                                 onPress={() => onPress(page)}
                                                 onLayout={onLayout}
                                                 activeOpacity={0.4}>
                                 <Animated.View
                                   style={{
                                     flex: 1,
                                     height: 100,
                                     backgroundColor: this.tabBg
                                   }}>
                                   <TabHeading scrollable
                                               style={{
                                                 backgroundColor: "transparent",
                                                 width: SCREEN_WIDTH / 2
                                               }}
                                               active={active}>
                                     <Animated.Text style={{
                                       fontWeight: active ? "bold" : "normal",
                                       color: this.textColor,
                                       fontSize: 14
                                     }}>
                                       {name}
                                     </Animated.Text>
                                   </TabHeading>
                                 </Animated.View>
                               </TouchableOpacity>
                             )}
                             underlineStyle={{backgroundColor: this.textColor}}/>
            </Animated.View>
            }>
            <Tab heading="Tab 1">
              {this.tabContent(30, 0)}
            </Tab>
            <Tab heading="Tab 2">
              {this.tabContent(15, 1)}
            </Tab>
          </Tabs>
        </Animated.ScrollView>
      </View>
    )
  }
}

问题:所有屏幕由于相同的偏移量而滚动

  1. 第四是一个模块粘性视差标题,您可以从这里使用选项卡式标题

存在的问题:由于它的模块没有很大的定制空间,但是已经足够了。而且当我使用它时,由于相同的偏移量,现在可能已经解决了一些问题,例如所有屏幕滚动。

所以基本上说他们都有一些问题,你以后必须解决。但我会推荐使用 netguru 的sticky-parallax-header 的第四个选项。

于 2020-09-29T10:17:08.713 回答