可容许的React Native中的可扩展滚动视图

时间:2017-12-21 19:30:10

标签: reactjs react-native

我正在寻找一种方法来实现React Native中显示的效果。我已经使用React Navigation实现了导航栏和标签栏设置。

当我整合如下所示的滚动时,现在出现了这个部分。实际上有一个包含大量行的视图。我尝试在ScrollView包裹的视图中设置它,但这太简单了,因为视图只是在屏幕上保持固定,我希望用视图移动地图。

我正在寻找伪代码。任何有React Native经验的人都能建议一个好的布局来达到这个效果吗?

enter image description here

1 个答案:

答案 0 :(得分:1)

我对此感到很有趣。只需在地图上创建一个简单的叠加层来显示您的服务列表,我们就可以达到同样的效果。叠加的状态将通过按钮上的回调呈现为可见,并通过“刷新”或从封装<ScrollView />下拉而变为不可见。

以下是此组件呈现的内容:

It's working! It's working!

这是组件类:

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