简体   繁体   English

React Native中可禁用和可扩展的滚动视图

[英]Dismissible & extendable scroll view in React Native

I am looking for a way to achieve the effect shown below in React Native. 我正在寻找一种实现React Native中所示效果的方法。 I have already achieved the navigation bar and tab bar setup using React Navigation. 我已经使用React Navigation实现了导航栏和标签栏的设置。

Now comes the part when I integrate a scroll like the one shown below. 现在,当我集成一个如下图所示的滚动条时,该部分就会出现。 Effectively there is a view with lots of rows in it. 实际上,其中有一个包含很多行的视图。 I tried setting this up in a view wrapped in a ScrollView but this is too simplistic as the view just remains fixed on the screen and I'm looking to move the map with the view. 我尝试在ScrollView包装的视图中进行设置,但这太简单了,因为该视图只是固定在屏幕上,并且我正在寻找随该视图移动地图的方法。

I'm looking for pseudocode if anything. 我在寻找伪代码(如果有)。 Can anyone with experience in React Native suggest a good layout to achieve this effect? 任何在React Native方面有经验的人都可以建议一个好的布局来实现这种效果吗?

在此处输入图片说明

I had a bit of fun with this. 我对此很开心。 We could achieve the same effect by just creating a simple overlay on your map to display your list of services. 我们可以通过在地图上创建一个简单的叠加层来显示服务列表来达到相同的效果。 The state of the overlay would be rendered visible from a callback on a button and rendered invisible by the 'refresh' or pull-down from an encapsulating <ScrollView /> . 叠加层的状态将从按钮上的回调显示为可见,并通过“刷新”或从封装的<ScrollView />的下拉<ScrollView />变为不可见。

Here's what this component renders: 这是此组件呈现的内容:

工作正常!工作正常!

Here's the component class: 这是组件类:

import React, { Component } from 'react';
import {
  Text,
  View,
  TouchableOpacity,
  StyleSheet,
  ScrollView,
  FlatList,
  Dimensions,
  RefreshControl
} from 'react-native';

export default class SO_MapOverlay extends Component {

    constructor(props) {
        super(props)
        this.state = {
            // Simple state variable to hide and show service list
            serviceListVisible: false,
            refreshing: false,
            data: [
                { key: 'item1' },
                { key: 'item2' },
                { key: 'item3' },
                { key: 'item4' },
                { key: 'item5' },
                { key: 'item6' },
                { key: 'item7' },
                { key: 'item8' }
            ],
        }
    }

    // Simply hides the button and shows the list overlay
    showRouteOverview() {
        this.setState({ serviceListVisible: true });
    }

    // Reverses showRouteOverview() when the user pulls down
    onRefresh() {
        this.setState({ refreshing: true });
        this.setState({ serviceListVisible: false });
        this.setState({ refreshing: false });
    }

    // Indicate the offset you want from the BOTTOM of the page
    renderSpacer(offset) {
        const { height } = Dimensions.get('window');
        const spacerOffset = height - parseInt(offset);
        return (
            <View style={{ height: spacerOffset, backgroundColor: 'transparent' }} />
        )
    }

    // Just renders each item in your flat list
    renderItem(itemData) {
        return(
            <View style={[styles.item]}>
                <Text style={{ color: 'black'}}>{itemData.item.key}</Text>
            </View>
        )
    }

    renderRefreshControl() {
        return (
            <RefreshControl
        refreshing={this.state.refreshing}
        onRefresh={this.onRefresh.bind(this)}
        // Note: I'm just hiding the activity monitor with these paramteres
          color='transparent'
          tintColor='transparent'
          />
        )
    }

    render() {
        const { serviceListVisible } = this.state;
        const listHeight = 56 * this.state.data.length;
        return (
          <View style={styles.container}>
            <View style={styles.mapContainer}>
                <Text style={{color: 'white'}}>I am map.</Text>
                <TouchableOpacity
                    style={[styles.showRouteOverviewButton, serviceListVisible ? styles.invisible : null]}
                    onPress={() => { this.showRouteOverview() }}>
                    <Text>Show Services</Text>
                </TouchableOpacity>
              </View>
              <ScrollView
                style={[styles.listContainer, serviceListVisible ? styles.visible : null ]}
                refreshControl={ this.renderRefreshControl() }>
                { this.renderSpacer(100) }
                <FlatList
                    style={[styles.list, { height: listHeight }]}
                    data={this.state.data}
                    renderItem={(itemData) => this.renderItem(itemData)}
                    keyExtractor={(item, index) => index}
                    scrollEnabled={false}
                    />
            </ScrollView>
          </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    visible: {
        display: 'flex'
    },
    invisible: {
        display: 'none'
    },
    mapContainer: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: 'gray',
        position: 'absolute',
        bottom: 0,
        right: 0,
        left: 0,
        top: 0,
    },
    showRouteOverviewButton: {
        position: 'absolute',
        bottom: 40,
        backgroundColor: 'white',
        paddingHorizontal: 20,
        paddingVertical: 10,
    },
    listContainer: {
        display: 'none',
        flex: 1,
    },
    list: {
        backgroundColor: 'red'
    },
    item: {
        alignItems: 'center',
        justifyContent: 'center',
        flex: 1,
        padding: 20,
        backgroundColor: 'white',
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM