1. 程式人生 > >react native 仿支付寶更多

react native 仿支付寶更多

公司要做一個支付寶更多的滑動效果。查詢react naive 沒有好的元件來實現。自己做了一個demo.

 

效果圖

 

程式碼實現:

import React, {Component} from 'react';
import {
    StyleSheet,
    View,
    ScrollView,
    Text,
} from 'react-native';
import  {deviceInfo} from '../../../utils'
import  ScrollableTab from '../../common/ScrollableTab'
export default class ZhiHuBao extends Component<{}> {

    constructor(props){
        super(props)
        this.state={
            dataType:['11','22','33','44','55','66','77'],
            itemHeight:[],
            stickyHeight:0,
            onMomentumScrollBegin:false,
        }

    }

    componentWillMount(){

    }



    changePosition(index){
        this.refs.ScrollableTab.changePosition(index)
    }

    callbackChangeIndex(index){
        this.state.onMomentumScrollBegin=true
        this.refs.ScrollView.scrollTo({x:0, y: this.state.itemHeight[index]-this.state.stickyHeight, animated: true})
    }


    _onScroll(e){
        if(!this.state.onMomentumScrollBegin){
            let newScrollOffset=e.nativeEvent.contentOffset.y+this.state.stickyHeight
        /*    if(newScrollOffset>=this.state.itemHeight[0]&&newScrollOffset<this.state.itemHeight[1]){
                console.log("item 1")
                this.changePosition(0)
            }else  if(newScrollOffset>=this.state.itemHeight[1]&&newScrollOffset<this.state.itemHeight[2]){
                console.log("item 2")
                this.changePosition(1)
            }else if(newScrollOffset>=this.state.itemHeight[2]&&newScrollOffset<this.state.itemHeight[3]){
                console.log("item 3")
                this.changePosition(2)
            }else if(newScrollOffset>=this.state.itemHeight[3]&&newScrollOffset<this.state.itemHeight[4]){
                console.log("item 4")
                this.changePosition(3)
            }else if(newScrollOffset>=this.state.itemHeight[4]&&newScrollOffset<this.state.itemHeight[5]){
                console.log("item 5")
                this.changePosition(4)
            }else if(newScrollOffset>=this.state.itemHeight[5]&&newScrollOffset<this.state.itemHeight[6]){
                console.log("item 5")
                this.changePosition(5)
            }else if(newScrollOffset>=this.state.itemHeight[6]){
                console.log("item 5")
                this.changePosition(6)
            }*/
            for(let i=0;i<this.state.itemHeight.length;i++){
                if(i==this.state.itemHeight.length-1&&newScrollOffset>=this.state.itemHeight[this.state.itemHeight.length-1]){
                    this.changePosition(i)
                    return
                }else if(newScrollOffset>=this.state.itemHeight[i]&&newScrollOffset<this.state.itemHeight[i+1]){
                    this.changePosition(i)
                    return
                }
            }

        }

    }


    _onLayout(e){
        console.log("_onLayout"+e.nativeEvent.layout.y)
        this.state.itemHeight.push(e.nativeEvent.layout.y)

    }
    _onLayout2(e){
         this.state.stickyHeight=e.nativeEvent.layout.height
    }

    _onScrollBeginDrag(){
        if( this.state.onMomentumScrollBegin==true){
            this.state.onMomentumScrollBegin=false
        }
    }

    render() {
        return (
            <ScrollView  ref={'ScrollView'} onScroll={this._onScroll.bind(this)} stickyHeaderIndices={[1]} onScrollBeginDrag={this._onScrollBeginDrag.bind(this)} >
                <View style={styles.head}>
                    <Text>這個是頭部</Text>
                </View>
                <ScrollableTab titleArr={this.state.dataType} ref={'ScrollableTab'} onLayout={this._onLayout2.bind(this)}  callback={this.callbackChangeIndex.bind(this)}/>
                <View style={[styles.item,{height:100}]}                            onLayout={this._onLayout.bind(this)}><Text>{this.state.dataType[0]}</Text></View>
                <View style={[styles.item,{height:140,backgroundColor:'#ddd'}]}     onLayout={this._onLayout.bind(this)}><Text>{this.state.dataType[1]}</Text></View>
                <View style={[styles.item,{height:60}]}                             onLayout={this._onLayout.bind(this)}><Text>{this.state.dataType[2]}</Text></View>
                <View style={[styles.item,{height:100,backgroundColor:'#ddd'}]}     onLayout={this._onLayout.bind(this)}><Text>{this.state.dataType[3]}</Text></View>
                <View style={[styles.item,{height:100}]}                            onLayout={this._onLayout.bind(this)}><Text>{this.state.dataType[4]}</Text></View>
                <View style={[styles.item,{height:120,backgroundColor:'#ddd'}]}     onLayout={this._onLayout.bind(this)}><Text>{this.state.dataType[5]}</Text></View>
                <View style={[styles.item,{height:deviceInfo.deviceHeight-40,backgroundColor:'#0ff'}]} onLayout={this._onLayout.bind(this)}><Text>{this.state.dataType[6]}</Text></View>
            </ScrollView>
        )
    }
}

const styles = StyleSheet.create({
    contain: {
        flex: 1,
        backgroundColor: '#f4f4f4',
        alignItems: 'center',

    },
    head:{
        width:deviceInfo.deviceWidth,
        height:150,
        backgroundColor:'#0f0',
        justifyContent:'center',
        alignItems:'center'
    },
    stickyHeader:{
        width:deviceInfo.deviceWidth,
        height:40,
        backgroundColor:'#0ff'
    },
    item:{
        width:deviceInfo.deviceWidth,
        height:80,
        backgroundColor:'#fff',
        justifyContent:'center',
        alignItems:'center'
    },


});

 

 

import React, {Component} from 'react';

import {
    Text,
    View,
    ScrollView,
    StyleSheet,
    TouchableOpacity
} from 'react-native';
import PropTypes from 'prop-types';


export default class ScrollableTab extends Component<{}> {

    static propTypes = {
        titleArr:PropTypes.array,
    }

    static defaultProps = {
    }

    constructor(props){
        super(props)
        this.state={
            titleArr:this.props.titleArr,
            position:0
        }
    }

    clickChange(index){
        if(index!=this.state.position){
            this.props.callback&&this.props.callback(index)
            this.changePosition(index)
        }
    }

    changePosition(index){
        if(index!=this.state.position){
            this.refs.ScrollView.scrollTo({x: index * 70, y: 0, animated: false})
            this.setState({
                position:index
            })
        }

    }

    render() {
        let tempView=[];
         const {titleArr,position}=this.state;
        for(let i=0;i<titleArr.length;i++){
            tempView.push(
                <TouchableOpacity  onPress={()=>this.clickChange(i)} key={i}>
                    <View style={position==i?styles.item:styles.unItem} >
                        <Text style={position==i?{color:'#0f0'}:{color:'#333'}}>{titleArr[i]}</Text>
                    </View>
                </TouchableOpacity>
            )
        }
        return (
            <ScrollView ref={'ScrollView'} horizontal={true}showsHorizontalScrollIndicator={false} style={{backgroundColor:'#999'}}>
                {tempView}
            </ScrollView>
        )
    }
}

const styles = StyleSheet.create({
     item:{
         height:40,
         width:70,
         justifyContent:'center',
         alignItems:'center',
     },
    unItem:{
        width:70,
        height:40,
        justifyContent:'center',
        alignItems:'center',
    },


});