如何防止模式窗口在Android的屏幕锁定中消失?

时间:2019-04-10 11:44:43

标签: javascript android react-native modal-dialog

我是React Native的新手,支持一个小型Android应用程序。在测试期间,我遇到了无法解决的模态错误。 在返回这个错误之前,我想尝试着自己尝试一下(当然,需要您的帮助)。

错误说明:在特定操作序列上,应用程序UI冻结,并且不响应用户交互。同时,Android硬件按钮可以正常工作。

App是基本的条形码扫描仪,可将GET请求发送到服务器并呈现响应。 如果响应数据包含错误标志,则显示带有相应信息和选项按钮的模式窗口。

我能够查明冻结发生的原因是: 如果警告模式在屏幕上保持活动状态,直到屏幕锁定(通过按按钮或屏幕锁定计时器)为止,则在屏幕上将不再显示进一步的解锁模式窗口。

尽管模态不可见,但基础视图对滚动或点击无响应,就像模态仍然存在一样。要摆脱它,我们需要重新启动整个应用程序。

模态窗口代码

// @flow
/* imports */

type Props = {
    warningText: ?string,
    options: ?string[],
    visible: boolean,
    onPress: (value: number) => void,
}

export default class WarningModal extends PureComponent<Props> {
    renderButtons = () => {
        /* code omitted */
    }

    render() {
        const { warningText, options, visible } = this.props
        return (
            <Modal
                visible={visible}
                fullScreen
                transparent
                onRequestClose={() => {}}
            >
                <View>
                    <View>
                        <Text>Title</Text>
                        <View>
                            <Text>{warningText}</Text>
                        </View>
                        {options && options.length > 0 ? this.renderButtons() : undefined}
                    </View>
                </View>
            </Modal>
        )
    }
}

app中将showModal设置为false的唯一两个位置在SceneComponent类中,如下所示:

  1. 在初始化状态变量时:
state = {
        unitInfo: new Unit(),
        showModal: false,
    }
  1. 在模式窗口中处理选项按钮按下的方法中
onWarningPress = async (value: number) => {
        const {
            userStore: {
                state: {
                    user,
                },
            },
        } = this.props
        const { unitInfo } = this.state
        try {
            await saveWarning(value, user)
            this.setState({ showModal: false })
        } catch (error) {
            Alert.showAlert()
        }
    }

到目前为止,我还没有找到解决该问题的方法,因此希望您能为我提供正确的方向,以指导如何避免在没有用户交互的情况下进行模式关闭。 期望的行为是警告模式会无限期地停留在屏幕上,直到用户按下选项按钮为止。

2 个答案:

答案 0 :(得分:1)

经过深入调查,我仍然不确定是什么导致了此问题。但是,我在代码中添加了一个粗略的修补程序,以强制Modal元素在屏幕锁定/解锁后保持可见状态。

检查应用程序的DOM树显示,尽管从字面上看不见,但Modal元素仍然存在于具有属性visible={true}的DOM树中。但是,使用this.forceUpdate()this.setState(this.state)或某些伪状态键强制重新渲染SceneComponent并没有任何效果。

因此,我采用了丑陋的方式,将showModal值切换为“ false”,然后在应用程序状态更改时恢复为“ true”,如下所示:

 componentDidMount() {
      AppState.addEventListener('change', this.toggleModal)
  }

  componentWillUnmount() {
      AppState.removeEventListener('change', this.toggleModal)
  }

  toggleModal = () => {   
       if (this.state.showModal === true) {
           this.setState({ showModal: false }) 
           this.setState({ showModal: true })
       }  
  }

此“更改”事件在屏幕锁定时触发,并且下次解锁屏幕时,模态在屏幕上可见,正如预期的那样。

答案 1 :(得分:0)

React Native <Modal />组件有故障。您可以通过将StyleSheet.absoluteFill样式应用于<View />来创建自己的模式组件,该样式将包装模式内容。