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

feat(android): add modal features #3680

Merged
merged 19 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ function registerDialog(Vue) {
type: Boolean,
default: true,
},
autoHideStatusBar: {
type: Boolean,
default: false,
},
autoHideNavigationBar: {
type: Boolean,
default: false,
},
},
render(h) {
const firstChild = getFirstComponent(this.$slots.default);
Expand All @@ -63,7 +71,7 @@ function registerDialog(Vue) {
});
}
}
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) {
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
Loading