Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NavigationBar 能否实现沉浸式状态栏 #116

Closed
auven opened this issue Dec 7, 2017 · 7 comments
Closed

NavigationBar 能否实现沉浸式状态栏 #116

auven opened this issue Dec 7, 2017 · 7 comments

Comments

@auven
Copy link
Contributor

auven commented Dec 7, 2017

想请问能否实现类似下面的状态栏:

状态栏透明,然后顶部背景渐变色。

@rilyu
Copy link
Owner

rilyu commented Dec 7, 2017

这是高度定制的组件了,NavigationBar 本身没有支持,你可以参考 NavigationBar 自行实现,实质就是在容器内放一张自由拉伸的图片

@auven
Copy link
Contributor Author

auven commented Dec 8, 2017

我昨天试了一下,可以采用这样的方法:

设置 react native StatusBar 组件的 backgroundColor 为透明(rgba(0,0,0,0)),并且 translucent 为 true 就能实现沉浸式状态栏。沉浸式状态栏在安卓4.4以上才能生效,所以还需要引入 react-native-device-info 针对不同的版本来做相应的处理。

对 teaset 的修改

NavigationBar.js

...

// 引入 react-native-device-info
import DeviceInfo from 'react-native-device-info';

...

style = [{
    ...
    // height: statusBarInsets && Platform.OS === 'ios' ? 64 : 44,
    height: (statusBarInsets && Platform.OS === 'ios') || parseFloat(DeviceInfo.getSystemVersion()) > 4.4 ? 64 : 44,
    // paddingTop: statusBarInsets && Platform.OS === 'ios' ? 20 : 0,
    paddingTop: (statusBarInsets && Platform.OS === 'ios') || parseFloat(DeviceInfo.getSystemVersion()) > 4.4 ? 20 : 0,
    ...
}].concat(style).concat({
    top: this.state.barTop, //hidden or shown
});

...

let titleViewStyle = {
    ...
    // top: statusBarInsets && Platform.OS === 'ios' ? 20 : 0,
    top: (statusBarInsets && Platform.OS === 'ios') || parseFloat(DeviceInfo.getSystemVersion()) > 4.4 ? 20 : 0,
    ...
};

...

{/* <StatusBar backgroundColor={statusBarColor} barStyle={statusBarStyle} animated={animated} hidden={statusBarHidden} /> */}
<StatusBar backgroundColor={'rgba(0,0,0,0)'} translucent={true} barStyle={statusBarStyle} animated={animated} hidden={statusBarHidden} />

...

NavigationPage.js

...

// 引入 react-native-device-info
import DeviceInfo from 'react-native-device-info';

...

let pageContainerStyle = [{
    flex: 1,
    padding: 0,
    // marginTop: navigationBarInsets ? (Platform.OS === 'ios' ? 64 : 44) : 0,
    marginTop: navigationBarInsets ? (Platform.OS === 'ios' || parseFloat(DeviceInfo.getSystemVersion()) > 4.4 ? 64 : 44) : 0,
}];

...

自己的项目还需配置

npm install --save react-native-device-info

# 注意 link 之后要重新 run
react-native link react-native-device-info

效果图

左边 6.0 右边 4.4

总结

感觉这样子会好看很多^v^,请问作者是否考虑添加沉浸式状态栏~?@rilyu

@rilyu
Copy link
Owner

rilyu commented Dec 8, 2017

感谢提供解决方案,建议:

1、Teaset 最初的设计是 0 依赖的,目前的依赖都是之前包含在 React Native 里,后来升级拆分出去的,0 依赖的目的是提供最好的版本兼容性,rn 升级时只需要处理 rn 的 Breaking changes 就可以了,不会因为第三方依赖而导致不可用,所以这个方案增加 react-native-device-info 依赖是与 Teaset 的设计理念相违背的,在自己的特定项目中使用则没有问题;
2、可使用 Platform.Version 代替使用 react-native-device-info 的版本检查,对应关系参考:https://stackoverflow.com/questions/3993924/get-android-api-level-of-phone-currently-running-my-application;
3、statusBarColor 需要保留兼容性,否则就无法设置 StatusBar 的背景色了,可把以下行

if (!statusBarColor) statusBarColor = fs.backgroundColor;

修改为

if (!statusBarColor) statusBarColor = Platform.Version > 20 ? 'rgba(0,0,0,0)' : fs.backgroundColor;

需要测试一下没问题后再 PR

@auven
Copy link
Contributor Author

auven commented Dec 8, 2017

按照你提供的方法,我重新修改了一下:

NavigationBar.js

...
style = [{
    ...
    // height: statusBarInsets && Platform.OS === 'ios' ? 64 : 44,
    // paddingTop: statusBarInsets && Platform.OS === 'ios' ? 20 : 0,
    height: statusBarInsets && Platform.OS === 'ios' || Platform.Version > 20 ? 64 : 44,
    paddingTop: statusBarInsets && Platform.OS === 'ios' || Platform.Version > 20 ? 20 : 0,
    ...
}].concat(style).concat({
    top: this.state.barTop, //hidden or shown
});
...
// if (!statusBarColor) statusBarColor = fs.backgroundColor;
if (!statusBarColor) statusBarColor = statusBarInsets && Platform.OS === 'ios' || Platform.Version > 20 ? 'rgba(0,0,0,0)' : fs.backgroundColor;
...
let titleViewStyle = {
    ...
    // top: statusBarInsets && Platform.OS === 'ios' ? 20 : 0,
    top: statusBarInsets && Platform.OS === 'ios' || Platform.Version > 20 ? 20 : 0,
    ...
};
...
{/* <StatusBar backgroundColor={statusBarColor} barStyle={statusBarStyle} animated={animated} hidden={statusBarHidden} /> */}
<StatusBar backgroundColor={statusBarColor} translucent={true} barStyle={statusBarStyle} animated={animated} hidden={statusBarHidden} />
...

NavigationPage.js

...
let pageContainerStyle = [{
    flex: 1,
    padding: 0,
    // marginTop: navigationBarInsets ? (Platform.OS === 'ios' ? 64 : 44) : 0,
    marginTop: navigationBarInsets ? (Platform.OS === 'ios' || Platform.Version > 20 ? 64 : 44) : 0,
}];
...

开启沉浸式状态栏后,安卓4.4以上发现的问题

OverlayPopoverView 会往上偏一些,如图

我猜测可能是开启沉浸式之后,状态栏高度消失

修改 OverlayPopoverView.js 后就正常了

...
// import {View, Dimensions, Platform} from 'react-native';
import {View, Dimensions, Platform, StatusBar} from 'react-native';
...
/*
let {x, y, width, height} = fromBounds ? fromBounds : {};
if (!x && x !== 0) x = screenWidth / 2;
if (!y && y !== 0) y = screenHeight / 2;
if (!width) width = 0;
if (!height) height = 0;
if (!directionInsets) directionInsets = 0;
if (!alignInsets) alignInsets = 0;
*/
let {x, y, width, height} = fromBounds ? fromBounds : {};
// 添加这一句
if (y) y = Platform.OS === 'android' && Platform.Version > 20 ? y + StatusBar.currentHeight : y;
if (!x && x !== 0) x = screenWidth / 2;
if (!y && y !== 0) y = screenHeight / 2;
if (!width) width = 0;
if (!height) height = 0;
if (!directionInsets) directionInsets = 0;
if (!alignInsets) alignInsets = 0;
...

请问这样修改可以么?可以的话我就提交上去 @rilyu

@rilyu
Copy link
Owner

rilyu commented Dec 8, 2017

谢谢,OverlayPopoverView.js 问题估计是 measure 与 measureInWindow 函数使用问题,可能需要增加 Breaking changes 才是彻底解决问题的方法,你先提交上来吧,后续我再看看怎么解决

@rilyu
Copy link
Owner

rilyu commented Dec 16, 2017

1a3574b

@Kevin9505
Copy link

image
请问怎么实现键底部的虚拟按键隐藏呢。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants