Quantcast
Channel: Active questions tagged react-native+android - Stack Overflow
Viewing all articles
Browse latest Browse all 29452

How to change view before Android App is put to background?

$
0
0

I have an App with two Views, blue view must be shown only when app is in active state (foreground) and the green view must be shown when app is put on background (e.g. clocking on hardware square button on Android).

enter image description here

The following picture shows what I currently get when I put the App in background state:

enter image description here

The following one is what I want to do when App is put on background (on iOS works, on Android not so well):

enter image description here

And this is the implementation.

Please, ignore for the moment that the component for iOS is almost identical to that for Android except for the style of the View. I was doing other tests with different components and for the moment it's okay for me to keep them like this. The difference between the two components (iOS / Android) lies in the style, because in iOS the zIndex works, while in Android I have to use elevation to overlap the views.

const showSecurityScreenFromAppState = appState =>
    ['background', 'inactive'].includes(appState);

const withSecurityScreenIOS = Wrapped => {
    return class WithSecurityScreen extends React.Component {
        constructor(props) {
            super(props);
        }

        state = {
            showSecurityScreen: showSecurityScreenFromAppState(AppState.currentState),
        };

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

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

        onChangeAppState = nextAppState => {
            const showSecurityScreen = showSecurityScreenFromAppState(nextAppState);

            this.setState({showSecurityScreen});
        };

        //this.state.showSecurityScreen
        render() {
            return (
                <>
                    <View style={[styles.container, {zIndex: this.state.showSecurityScreen ? 1 : -1}]}>
                        <View style={{flex: 1, backgroundColor: globalStyles.colors.customerGreen}}>
                            <View style={styles.upperView}>
                                <Text style={styles.upperViewText}>MyApp</Text>
                            </View>
                        </View>
                    </View>
                    <Wrapped {...this.props}/>
                </>
            );
        }
    };
};

const withSecurityScreenAndroid = Wrapped => {
    return class WithSecurityScreen extends React.Component {
        constructor(props) {
            super(props);
        }

        state = {
            showSecurityScreen: showSecurityScreenFromAppState(AppState.currentState),
        };

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

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

        onChangeAppState = nextAppState => {
            const showSecurityScreen = showSecurityScreenFromAppState(nextAppState);

            this.setState({showSecurityScreen});
        };

        //this.state.showSecurityScreen
        render() {
            return (
                <>
                    <View style={[styles.container, {elevation: this.state.showSecurityScreen ? 1 : -1}]}>
                        <View style={{flex: 1, backgroundColor: globalStyles.colors.customerGreen}}>
                            <View style={styles.upperView}>
                                <Text style={styles.upperViewText}>MyApp</Text>
                            </View>
                        </View>
                    </View>
                    <Wrapped {...this.props}/>
                </>
            );
        }
    };
};

export const withSecurityScreen =
    Platform.OS === 'ios' ? withSecurityScreenIOS : withSecurityScreenAndroid;

There is not problems in the code, it works very well in iOS, but on Android sometimes it works and sometimes it doesn't. I suspect the cause is that Android OS, when the square button is pressed, it takes a screenshot of the current view and uses it as a background image of the App. Sometimes, however, it happens that the change of layer (elevation) is faster than the Android screenshot and therefore I can see the green screen in the background, as Android is using it as an image.

Is there a way to synchronize these operations? That is: can I make sure that when I press the square button, Android waits for the view to change and then let it go in the background?

Note: I have tested the functioning of elevation when the app is in the foreground, simply inverting the values of elevation when it is in the background or in the foreground, I assure that elevation is working.


Viewing all articles
Browse latest Browse all 29452

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>