Skip to content

Commit

Permalink
feat(android): add modal features (Tencent#3680)
Browse files Browse the repository at this point in the history
Co-authored-by: andrezhuang <[email protected]>
Co-authored-by: OpenHippy <[email protected]>
  • Loading branch information
3 people authored Feb 1, 2024
1 parent e24cc61 commit 98df553
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 20 deletions.
2 changes: 2 additions & 0 deletions docs/api/hippy-react/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ import icon from './qb_icon_new.png';
| supportedOrientations | 支持屏幕翻转方向 | `enum (portrait, portrait-upside-down, landscape, landscape-left, landscape-right)[]` | `iOS` |
| immersionStatusBar | 是否是沉浸式状态栏。`default: false` | `boolean` | `Android、Voltron` |
| darkStatusBarText | 是否是亮色主体文字,默认字体是黑色的,改成 true 后会认为 Modal 背景为暗色调,字体就会改成白色。 | `boolean` | `Android、iOS、Voltron` |
| autoHideStatusBar | 是否在`Modal`显示时自动隐藏状态栏。<strong>Android 中仅 api28 以上生效。</strong> `default: false` | `boolean` | `Android` |
| autoHideNavigationBar | 是否在`Modal`显示时自动隐藏导航栏。 `default: false` | `boolean` | `Android` |
| onShow |`Modal`显示时会执行此回调函数。 | `Function` | `Android、iOS、hippy-react-web、Web-Renderer、Voltron` |
| onOrientationChange | 屏幕旋转方向改变时执行会回调 | `Function` | `Android、iOS` |
| onRequestClose |`Modal` 请求关闭时会执行此回调函数,一般时在 Android 系统里按下硬件返回按钮时触发,一般要在里面处理关闭弹窗。 | `Function` | `Android、hippy-react-web、Voltron` |
Expand Down
3 changes: 3 additions & 0 deletions docs/api/hippy-vue/external-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ export default {
| supportedOrientations | 支持屏幕翻转方向 | `enum(portrait, portrait-upside-down, landscape, landscape-left, landscape-right)[]` | `iOS` |
| immersionStatusBar | 是否是沉浸式状态栏。`default: true` | `boolean` | `Android、Voltron` |
| darkStatusBarText | 是否是亮色主体文字,默认字体是黑色的,改成 true 后会认为 Modal 背景为暗色调,字体就会改成白色。 | `boolean` | `Android、iOS、Voltron` |
| autoHideStatusBar | 是否在`Modal`显示时自动隐藏状态栏。<strong>Android 中仅 api28 以上生效。</strong> `default: false` | `boolean` | `Android` |
| autoHideNavigationBar | 是否在`Modal`显示时自动隐藏导航栏。 `default: false` | `boolean` | `Android` |

| transparent | 背景是否是透明的。`default: true` | `boolean` | `Android、iOS、Web-Renderer、Voltron` |

## 事件
Expand Down
53 changes: 48 additions & 5 deletions driver/js/examples/hippy-react-demo/src/components/Modal/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ const styles = StyleSheet.create({
},
selectionText: {
fontSize: 20,
color: SKIN_COLOR.mainLight,
textAlign: 'center',
textAlignVertical: 'center',
marginLeft: 10,
marginRight: 10,
padding: 5,
borderRadius: 5,
borderWidth: 2,
},
});

Expand All @@ -55,6 +57,9 @@ export default class ModalExpo extends React.Component {
visible: false,
press: false,
animationType: 'fade',
immerseStatusBar: false,
hideStatusBar: false,
hideNavigationBar: false,
};
this.show = this.show.bind(this);
this.hide = this.hide.bind(this);
Expand Down Expand Up @@ -98,24 +103,62 @@ export default class ModalExpo extends React.Component {
<View style={{flexDirection: 'row', justifyContent: 'center', marginTop: 20}}>
<Text
onClick={() => {this.setState({animationType: 'fade'})}}
style={[styles.selectionText, {backgroundColor: this.state.animationType === 'fade' ? 'rgba(255, 0, 0, 0.5)' : '#FFFFFF'}]}
style={[styles.selectionText,
{borderColor: this.state.animationType === 'fade' ? 'red' : SKIN_COLOR.mainLight},
{color: this.state.animationType === 'fade' ? 'red' : SKIN_COLOR.mainLight}
]}
>fade</Text>
<Text
onClick={() => {this.setState({animationType: 'slide'})}}
style={[styles.selectionText, {backgroundColor: this.state.animationType === 'slide' ? 'rgba(255, 0, 0, 0.5)' : '#FFFFFF'}]}
style={[styles.selectionText,
{borderColor: this.state.animationType === 'slide' ? 'red' : SKIN_COLOR.mainLight},
{color: this.state.animationType === 'slide' ? 'red' : SKIN_COLOR.mainLight}
]}
>slide</Text>
<Text
onClick={() => {this.setState({animationType: 'slide_fade'})}}
style={[styles.selectionText, {backgroundColor: this.state.animationType === 'slide_fade' ? 'rgba(255, 0, 0, 0.5)' : '#FFFFFF'}]}
style={[styles.selectionText,
{borderColor: this.state.animationType === 'slide_fade' ? 'red' : SKIN_COLOR.mainLight},
{color: this.state.animationType === 'slide_fade' ? 'red' : SKIN_COLOR.mainLight}
]}
>slide_fade</Text>
</View>
<View style={{flexDirection: 'row', justifyContent: 'center', marginTop: 20}}>
<Text
onClick={() => {this.setState({hideStatusBar: !this.state.hideStatusBar})}}
style={[styles.selectionText,
{borderColor: this.state.hideStatusBar ? 'red' : SKIN_COLOR.mainLight},
{color: this.state.hideStatusBar ? 'red' : SKIN_COLOR.mainLight}
]}
>autoHideStatusBar</Text>
</View>
<View style={{flexDirection: 'row', justifyContent: 'center', marginTop: 20}}>
<Text
onClick={() => {this.setState({immerseStatusBar: !this.state.immerseStatusBar})}}
style={[styles.selectionText,
{borderColor: this.state.immerseStatusBar ? 'red' : SKIN_COLOR.mainLight},
{color: this.state.immerseStatusBar ? 'red' : SKIN_COLOR.mainLight}
]}
>immersionStatusBar</Text>
</View>
<View style={{flexDirection: 'row', justifyContent: 'center', marginTop: 20}}>
<Text
onClick={() => {this.setState({hideNavigationBar: !this.state.hideNavigationBar})}}
style={[styles.selectionText,
{borderColor: this.state.hideNavigationBar ? 'red' : SKIN_COLOR.mainLight},
{color: this.state.hideNavigationBar ? 'red' : SKIN_COLOR.mainLight}
]}
>autoHideNavigationBar</Text>
</View>
<Modal
transparent={true}
animationType={this.state.animationType}
visible={visible}
onRequestClose={() => { /* Trigger when hardware back pressed */ }}
supportedOrientations={['portrait']}
immersionStatusBar={true}
immersionStatusBar={this.state.immerseStatusBar}
autoHideStatusBar={this.state.hideStatusBar}
autoHideNavigationBar={this.state.hideNavigationBar}
>
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center', backgroundColor: '#4c9afa88' }}>
<View
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,36 @@
>
<span class="button-text">显示对话框--slide_fade</span>
</button>
<button
:style="[{ borderColor: autoHideStatusBar ? '#FF0000' : '#40b883'}]"
class="dialog-demo-button-1"
@click="() => clickDialogConfig('hideStatusBar')"
>
<span class="button-text">隐藏状态栏</span>
</button>
<button
:style="[{ borderColor: immersionStatusBar ? '#FF0000' : '#40b883'}]"
class="dialog-demo-button-1"
@click="() => clickDialogConfig('immerseStatusBar')"
>
<span class="button-text">沉浸式状态栏</span>
</button>
<button
:style="[{ borderColor: autoHideNavigationBar ? '#FF0000' : '#40b883'}]"
class="dialog-demo-button-1"
@click="() => clickDialogConfig('hideNavigationBar')"
>
<span class="button-text">隐藏导航栏</span>
</button>
<!-- dialog 无法支持 v-show,只能使用 v-if 进行显式切换 -->
<dialog
v-if="dialogIsVisible"
:animationType="dialogAnimationType"
:transparent="true"
:supportedOrientations="supportedOrientations"
:immersionStatusBar="immersionStatusBar"
:autoHideStatusBar="autoHideStatusBar"
:autoHideNavigationBar="autoHideNavigationBar"
@show="onShow"
@requestClose="onClose"
>
Expand Down Expand Up @@ -52,6 +76,9 @@
v-if="dialog2IsVisible"
:animationType="dialogAnimationType"
:transparent="true"
:immersionStatusBar="immersionStatusBar"
:autoHideStatusBar="autoHideStatusBar"
:autoHideNavigationBar="autoHideNavigationBar"
@requestClose="onClose"
>
<div
Expand Down Expand Up @@ -93,6 +120,9 @@ export default {
dialogIsVisible: false,
dialog2IsVisible: false,
dialogAnimationType: '',
immersionStatusBar: false,
autoHideStatusBar: false,
autoHideNavigationBar: false,
};
},
methods: {
Expand All @@ -106,6 +136,21 @@ export default {
evt.stopPropagation(); // 二级弹窗关闭时会冒泡到这里,所以也要阻止一下冒泡防止一级 dialog 消失
this.dialog2IsVisible = !this.dialog2IsVisible;
},
clickDialogConfig(option) {
switch (option) {
case 'hideStatusBar':
this.autoHideStatusBar = !this.autoHideStatusBar;
break;
case 'immerseStatusBar':
this.immersionStatusBar = !this.immersionStatusBar;
break;
case 'hideNavigationBar':
this.autoHideNavigationBar = !this.autoHideNavigationBar;
break;
default:
break;
}
},
onShow() {
console.log('Dialog is opening');
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,37 @@
>
<span class="button-text">显示对话框--slide_fade</span>
</button>
<button
:style="[{ borderColor: autoHideStatusBar ? '#FF0000' : '#40b883'}]"
class="dialog-demo-button-1"
@click.stop="() => onClickDialogConfig('hideStatusBar')"
>
<span class="button-text">隐藏状态栏</span>
</button>
<button
:style="[{ borderColor: immersionStatusBar ? '#FF0000' : '#40b883'}]"
class="dialog-demo-button-1"
@click.stop="() => onClickDialogConfig('immerseStatusBar')"
>
<span class="button-text">沉浸式状态栏</span>
</button>
<button
:style="[{ borderColor: autoHideNavigationBar ? '#FF0000' : '#40b883'}]"
class="dialog-demo-button-1"
@click.stop="() => onClickDialogConfig('hideNavigationBar')"
>
<span class="button-text">隐藏导航栏</span>
</button>
<!-- dialog can't support v-show, can only use v-if for explicit switching -->

<dialog
v-if="dialogIsVisible"
:animationType="dialogAnimationType"
:transparent="true"
:supportedOrientations="supportedOrientations"
:immersionStatusBar="immersionStatusBar"
:autoHideStatusBar="autoHideStatusBar"
:autoHideNavigationBar="autoHideNavigationBar"
@show="onShow"
@requestClose="onClose"
>
Expand Down Expand Up @@ -93,11 +117,32 @@ export default defineComponent({
const dialog2IsVisible = ref(false);
// dialog 动画效果
const dialogAnimationType = ref('fade');
// 是否沉浸式状态栏
const immersionStatusBar = ref(false);
// 是否隐藏状态栏
const autoHideStatusBar = ref(false);
// 是否隐藏导航栏
const autoHideNavigationBar = ref(false);
const onClickView = (type = '') => {
dialogIsVisible.value = !dialogIsVisible.value;
dialogAnimationType.value = type;
};
const onClickDialogConfig = (option) => {
switch (option) {
case 'hideStatusBar':
autoHideStatusBar.value = !autoHideStatusBar.value;
break;
case 'immerseStatusBar':
immersionStatusBar.value = !immersionStatusBar.value;
break;
case 'hideNavigationBar':
autoHideNavigationBar.value = !autoHideNavigationBar.value;
break;
default:
break;
}
};
const onClickOpenSecond = (evt) => {
evt.stopPropagation();
dialog2IsVisible.value = !dialog2IsVisible.value;
Expand Down Expand Up @@ -139,11 +184,15 @@ export default defineComponent({
dialogIsVisible,
dialog2IsVisible,
dialogAnimationType,
immersionStatusBar,
autoHideStatusBar,
autoHideNavigationBar,
stopPropagation,
onClose,
onShow,
onClickView,
onClickOpenSecond,
onClickDialogConfig,
};
},
});
Expand Down
7 changes: 7 additions & 0 deletions driver/js/packages/hippy-react/src/components/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ interface ModalProps {
*/
autoHideStatusBar?: boolean;

/**
* Hide navigation bar when Modal is showing
*
* Default: false
*/
autoHideNavigationBar?: boolean;

/**
* The animation effect when toggle
*
Expand Down
12 changes: 11 additions & 1 deletion driver/js/packages/hippy-vue-native-components/src/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ function registerDialog(Vue: any) {
type: Boolean,
default: true,
},
autoHideStatusBar: {
type: Boolean,
default: false,
},
autoHideNavigationBar: {
type: Boolean,
default: false,
},
},
render(h: any) {
const firstChild = getFirstComponent(this.$slots.default);
Expand All @@ -63,7 +71,7 @@ function registerDialog(Vue: any) {
});
}
}
const { collapsable, transparent, immersionStatusBar } = this;
const { collapsable, transparent, immersionStatusBar, autoHideStatusBar, autoHideNavigationBar } = this;
return h(
'hi-dialog',
{
Expand All @@ -72,6 +80,8 @@ function registerDialog(Vue: any) {
collapsable,
transparent,
immersionStatusBar,
autoHideStatusBar,
autoHideNavigationBar,
},
},
this.$slots.default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export function registerDialog(): void {
transparent: true,
immersionStatusBar: true,
collapsable: false,
autoHideStatusBar: false,
autoHideNavigationBar: false,
},
defaultNativeStyle: {
position: 'absolute',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ public void setAnimationType(HippyModalHostView view, String animationType) {
view.setAnimationType(animationType);
}

@HippyControllerProps(name = "autoHideStatusBar", defaultType = HippyControllerProps.BOOLEAN)
public void autoHideStatusBar(HippyModalHostView view, boolean fullScreen) {
view.autoHideStatusBar(fullScreen);
}

@HippyControllerProps(name = "autoHideNavigationBar", defaultType = HippyControllerProps.BOOLEAN)
public void autoHideNavigationBar(HippyModalHostView view, boolean fullScreen) {
view.autoHideNavigationBar(fullScreen);
}

@HippyControllerProps(name = "immersionStatusBar", defaultType = HippyControllerProps.BOOLEAN)
public void setEnterImmersionStatusBar(HippyModalHostView view, boolean fullScreen) {
view.setEnterImmersionStatusBar(fullScreen);
Expand Down
Loading

0 comments on commit 98df553

Please sign in to comment.