preface

The title bar and status bar are not traditional black or white, but transparent, so that the mobile application interface takes up the whole screen space. When the page scrolls down from the top, the status bar and title content slowly changes from transparent to opaque, and exit the immersion mode. The above interaction is mainly achieved by setting the StatusBar StatusBar and opacity.

Set the opacity

In the initial case, the opacity of the title bar and status bar is 0. After scrolling down the page for a certain distance (set as the height of the title bar), the opacity gradually changes from 0 to 1. Opacity = opacity/height of title bar

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 // The height of the top title bar
		}
		// Top title bar
		this.titleBarView = null
	}

	// Listen for list scrolling events
	scrollViewScroll = (event) = > {
		const y = event.nativeEvent.contentOffset.y
		// Set the transparency of the title bar and status bar titleOpacity
		// When the scrolling distance of the page equals the height of the title bar, its transparency changes to 1
		const scale = y * 1.0 / this.state.titleBarHeight
		this.titleBarView.setState({
			titleOpacity: scale,
		})
	}

	render() {
		const { titleBarHeight} = this.state
		return (
			<View>{/* Immersive title */}<TitleBar
					onRef={(ref)= > this.titleBarView = ref}
					titleBarHeight={titleBarHeight}
				/>
				<ScrollView
					onScroll={this.scrollViewScroll}
				>
					<Text>The page content</Text>
				</ScrollView>
			</View>)}}Copy the code

Set the StatusBar

On ios, the status bar is immersive by default and by default, the content of the View is drawn from the top of the screen; On Android, the status bar will cover the topic content, so you need to set the status bar transparent

  • BarStyle sets the color of the status bar text
  • Always specifies whether the status bar is always transparent. When set to true, the app draws under the status bar (called “immersive”) — Android
  • BackgroundColor status bar 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
}
Copy the code

Set the title bar

  • The height of the entire title bar should equal the height of the status bar statusBarHeight plus the height of the title module titleBarHeight

Get the height of the status bar:

import { Platform, NativeModules } from "react-native"
const { StatusBarManager } = NativeModules
// Get the height of the status bar
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
})
Copy the code
  • The title bar must be set to absolute position, so that the title bar is displayed above the main content of the phone, so that the main content takes up the whole screen space

Complete code:

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 = {
			// Background transparency
			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}}] >{/* Title bar subject content */}</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',}})Copy the code

Original address: yolkpie.net/2020/12/07/…