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

效果图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
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,050评论 3 119
  • 前一段时间我们辩论咖举办了一场大型的活动,我们自认为宣传的很到位,但是你有没有看到宣传并参与我们的活动呢? 没有参...
    姬樱阅读 4,026评论 15 6
  • 看过这么一篇文章,《张允和与周有光:找个有趣的人一起变老》,摘自一本书。 张允和是谁?合肥四姐妹之一,她在张家排行...
    雨洁随笔阅读 3,401评论 0 1
  • 今天和小朋友问了风来了的游戏,你们觉得今天又风吗?所有的小朋友会说没有,我开始让身体摇晃起来并说哇,风来了。当我这...
    饶娟阅读 3,780评论 0 0
  • 去年 “挺五派”和“倒五派”大战三百个回合 成功将“五仁月饼” 推上“奇葩之王”的宝座 但在今年 奇葩月饼辈出,“...
    利赠商城阅读 1,228评论 0 0