React Native开发React Native学习react-native开发

react native 自定义导航栏随滚动渐变

2018-08-25  本文已影响239人  tomorrow_chen

效果图1 未滚动页面

image.png

效果图2 滚动页面

image.png

使用方式

import React, { Component } from 'react'
import NavPage from './NavPage'
import { View, ScrollView, Image, Dimensions, Platform } from 'react-native'

let { width } = Dimensions.get('window')
let navHeight = (Platform.OS === 'ios' ? 20 : 0) + 45

export default class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      opacity: 0
    }
  }

  onScroll = (event) => {
    let offsetY = event.nativeEvent.contentOffset.y
    let opacity = offsetY / navHeight
    // if(opacity > 5 || opacity < -5) { // 这里可以优化减少render, 1和0 滑快了会有些影响, 这里你可以看着给值, 当然也可以不优化
    //   return
    // }
    this.setState({
      opacity
    }) 
  }

  render() {
    return (
      <View style={{ alignItems: 'center' }}>
        <NavPage title={'详情页'} opacity={this.state.opacity} />
        <ScrollView
          showsVerticalScrollIndicator={false}
          ref='scroll'
          onScroll={this.onScroll}
          scrollEventThrottle={10}>
          <Image style={{ width: width, height: 300 }} source={{ uri: 'https://dimg07.c-ctrip.com/images/100e0t000000ihd4r494C_C_500_280.jpg' }} />
          <Image style={{ width: width, height: 300, marginTop: 20 }} source={{ uri: 'https://dimg04.c-ctrip.com/images/300e0q000000g5o8b658A_C_500_280.jpg' }} />
          <Image style={{ width: width, height: 300, marginTop: 20 }} source={{ uri: 'https://dimg04.c-ctrip.com/images/100l0s000000hg344225B_C_500_280.jpg' }} />
          <Image style={{ width: width, height: 300, marginTop: 20 }} source={{ uri: 'https://youimg1.c-ctrip.com/target/100f0d0000006xaav4A5E_C_220_110.jpg' }} />
        </ScrollView>
      </View>
    )
  }
}

自定义导航 NavPage.js

import React, { Component } from 'react';
import { View, Text, Image, StyleSheet, TouchableOpacity, Platform, Dimensions } from 'react-native';


/**
 * 自定义导航栏
 */
let height = (Platform.OS === 'ios' ? 20 : 0) + 45
export default class NavPage extends Component {

  render() {
    let { opacity, children, title } = this.props
    return (
      <View style={[styles.container, { backgroundColor: `rgba(16,94,174, ${opacity})` }]}>
        <TouchableOpacity style={styles.item} onPress={() => { alert('返回') }}>
          <Image style={styles.icon} source={require('./arrow.png')} />
        </TouchableOpacity>
        {

          <View style={{ alignItems: 'center', flex: 1 }}>
            {
              opacity < 0.4 ? null :
                (children || <Text style={{ color: '#FFF', fontSize: 17 }}>{title}</Text>)
            }
          </View>
        }
        <TouchableOpacity style={styles.item} onPress={() => { alert('更多') }}>
          <Image style={[styles.icon, { width: 25, height: 5 }]} source={require('./more.png')} />
        </TouchableOpacity>

      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    width: Dimensions.get('window').width,
    height: height,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingTop: Platform.OS === 'ios' ? 20 : 0,
    paddingHorizontal: 10,
    position: 'absolute',
    zIndex: 10
  },
  icon: {
    width: 21,
    height: 21,
  },
  item: {
    height: 30,
    width: 30,
    justifyContent: 'center',
    alignItems: 'center'
  }
})

NavPage.defaultProps = {
  title: 'title',
  opacity: 0
}
上一篇 下一篇

猜你喜欢

热点阅读