最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • react-native实现沉浸式标题栏

    正文概述 掘金(yolkpie)   2021-02-26   857

    前言

    沉浸式标题栏,简单来说,即是透明栏,标题栏和状态栏不再是传统的黑色或白色,而是透明的,使得手机应用界面占据整个屏幕空间,页面从上向下滚动时,状态栏和标题内容慢慢由透明变成不透明,退出沉浸模式。以上交互,主要通过设置状态栏 StatusBar 和 透明度 opacity 来实现。

    设置 opacity

    初始情况下,标题栏和状态栏的透明度opacity为0,页面向下滚动一段距离(这里设定为标题栏的高度)后,其透明度一点点的由0变为1。
    基本思路是:
    const opacity = 滚动的距离 / 标题栏的高度
    完整代码:

    import React, {PureComponent} from 'react'
    import { View, Text, ScrollView } from 'react-native'
    import TitleBar from '../../components/TitleBar'
    
    export default class TitlePage extends PureComponent {
    	constructor(props) {
    		super(props)
    		this.state = {
    			titleBarHeight: 50 // 顶部标题栏的高度
    		}
    		// 顶部标题栏
    		this.titleBarView = null
    	}
    
    	// 监听列表滚动事件
    	scrollViewScroll = (event) => {
    		const y = event.nativeEvent.contentOffset.y
    		// 设置标题栏和状态栏的透明度 titleOpacity
    		// 当页面滚动的距离等于标题栏的高度时,其透明度变为1
    		const scale = y * 1.0 / this.state.titleBarHeight
    		this.titleBarView.setState({
    			titleOpacity: scale,
    		})
    	}
    
    	render() {
    		const { titleBarHeight} = this.state
    		return (
    			<View>
    				{/*沉浸式标题*/}
    				<TitleBar
    					onRef={(ref) => this.titleBarView = ref}
    					titleBarHeight={titleBarHeight}
    				/>
    				<ScrollView
    					onScroll={this.scrollViewScroll}
    				>
    					<Text>页面内容</Text>
    				</ScrollView>
    			</View>
    		)
    	}
    }
    

    设置 StatusBar

    在 ios 端,状态栏默认是沉浸式的默认情况下, View 的内容会从屏幕顶部开始绘制;在 android 端,状态栏会遮住主题内容,需设置状态栏是否透明

    • barStyle 设置状态栏文本的颜色
    • translucent 指定状态栏是否透明。设置为true时,应用会在状态栏之下绘制(即所谓“沉浸式”)-- android
    • backgroundColor 状态栏背景色 -- android
    _renderStatusBar = () => {
        const { titleOpacity } = this.state
        const backgroundColor = `rgba(0, 0, 0, ${titleOpacity})`
        if (Platform.OS === 'ios') {
            return <StatusBar barStyle={'dark-content'}/>
        } else if (Platform.OS === 'android') {
            return <StatusBar
                backgroundColor={backgroundColor}
                barStyle={'dark-content'}
                translucent={true}/>
        }
        return null
    }
    

    设置标题栏

    • 整个标题栏的高度应该等于状态栏的高度 statusBarHeight 加上 标题模块的高度 titleBarHeight

    获取状态栏的高度:

    import { Platform, NativeModules } from "react-native"
    const { StatusBarManager } = NativeModules
    // 获取状态栏的高度
    const getStatusBarHeight = () => {
    	return new Promise((resolve) => {
    		const OS = Platform.OS
    		if (OS === 'ios') {
    			StatusBarManager.getHeight(statusBarHeight => {
    				resolve(statusBarHeight)
    			})
    		} else if (OS === 'android') {
    			resolve(StatusBarManager || {}).HEIGHT || 0
    		}
    		resolve(0)
    	})
    
    }
    let statusBarHeight = 0
    getStatusBarHeight().then((res) => {
        statusBarHeight = res
    })
    
    • 标题栏需设置成 absolute 定位,这样标题栏展示在手机主体内容上层,使得主体内容占据整个屏幕空间

    完整代码:

    import React, {PureComponent} from 'react'
    import {
    	View,
    	StatusBar,
    	StyleSheet,
    	Platform
    } from 'react-native'
    import { statusBarHeight } from '../common/globalData'
    
    export default class TitleBar extends PureComponent {
    	constructor(props) {
    		super(props)
    		this.props.onRef(this)
    		this.state = {
    			// 背景透明度
    			titleOpacity: 0
    		}
    	}
    	_renderStatusBar = () => {
    		const { titleOpacity } = this.state
    		const backgroundColor = `rgba(0, 0, 0, ${titleOpacity})`
    		if (Platform.OS === 'ios') {
    			return <StatusBar barStyle={'dark-content'}/>
    		} else if (Platform.OS === 'android') {
    			return <StatusBar
    				backgroundColor={backgroundColor}
    				barStyle={'dark-content'}
    				translucent={true}/>
    		}
    		return null
    	}
    	render() {
    		const { titleBarHeight } = this.props
    		const { titleOpacity } = this.state
    		return (
    			<View style={[{height: titleBarHeight + statusBarHeight}, TitleStyle.titleBarWrapper]}>
    				{this._renderStatusBar()}
    				<View style={[TitleStyle.titleBarBg, {
    					opacity: titleOpacity,
    				}]}/>
    				<View style={[TitleStyle.titleBarContent, {
    					marginTop: statusBarHeight,
    					height: titleBarHeight
    				}]}>
    				  {/*	标题栏主题内容*/}
    				</View>
    			</View>
    		)
    	}
    }
    
    const TitleStyle = StyleSheet.create({
    	titleBarWrapper: {
    		flexDirection: 'row',
    		position: 'absolute',
    		top: 0,
    		zIndex: 100,
    		width: '100%'
    	},
    	titleBarContent: {
    		alignItems: 'center',
    		justifyContent: 'center',
    		width: '100%',
    		height: 50,
    	},
    	titleBarBg: {
    		position: 'absolute',
    		top: 0,
    		height: '100%',
    		width: '100%',
    		backgroundColor: '#fff',
    	}
    })
    

    原文地址:https://yolkpie.net/2020/12/07/react-native%E5%AE%9E%E7%8E%B0%E6%B2%89%E6%B5%B8%E5%BC%8F%E6%A0%87%E9%A2%98%E6%A0%8F/


    起源地下载网 » react-native实现沉浸式标题栏

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元