Browse Source

Allow hiding the Android navigation bar (#6033)

This PR introduces an options to control the NavigationBar's visibility on Android.
```js
navigationBar: {
  visible: false
}
```
Co-authored-by: Guy Carmeli <guyc@wix.com>
Miki 4 years ago
parent
commit
7f6353bcea
No account linked to committer's email address

+ 7
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/NavigationBarOptions.java View File

1
 package com.reactnativenavigation.parse;
1
 package com.reactnativenavigation.parse;
2
 
2
 
3
+import com.reactnativenavigation.parse.params.Bool;
3
 import com.reactnativenavigation.parse.params.Colour;
4
 import com.reactnativenavigation.parse.params.Colour;
5
+import com.reactnativenavigation.parse.params.NullBool;
4
 import com.reactnativenavigation.parse.params.NullColor;
6
 import com.reactnativenavigation.parse.params.NullColor;
7
+import com.reactnativenavigation.parse.parsers.BoolParser;
5
 import com.reactnativenavigation.parse.parsers.ColorParser;
8
 import com.reactnativenavigation.parse.parsers.ColorParser;
6
 
9
 
7
 import org.json.JSONObject;
10
 import org.json.JSONObject;
12
         if (json == null) return result;
15
         if (json == null) return result;
13
 
16
 
14
         result.backgroundColor = ColorParser.parse(json, "backgroundColor");
17
         result.backgroundColor = ColorParser.parse(json, "backgroundColor");
18
+        result.isVisible = BoolParser.parse(json, "visible");
15
 
19
 
16
         return result;
20
         return result;
17
     }
21
     }
18
 
22
 
19
     public Colour backgroundColor = new NullColor();
23
     public Colour backgroundColor = new NullColor();
24
+    public Bool isVisible = new NullBool();
20
 
25
 
21
     public void mergeWith(NavigationBarOptions other) {
26
     public void mergeWith(NavigationBarOptions other) {
22
         if (other.backgroundColor.hasValue()) backgroundColor = other.backgroundColor;
27
         if (other.backgroundColor.hasValue()) backgroundColor = other.backgroundColor;
28
+        if (other.isVisible.hasValue()) isVisible = other.isVisible;
23
     }
29
     }
24
 
30
 
25
     public void mergeWithDefault(NavigationBarOptions defaultOptions) {
31
     public void mergeWithDefault(NavigationBarOptions defaultOptions) {
26
         if (!backgroundColor.hasValue()) backgroundColor = defaultOptions.backgroundColor;
32
         if (!backgroundColor.hasValue()) backgroundColor = defaultOptions.backgroundColor;
33
+        if (!isVisible.hasValue()) isVisible = defaultOptions.isVisible;
27
     }
34
     }
28
 }
35
 }

+ 19
- 2
lib/android/app/src/main/java/com/reactnativenavigation/presentation/Presenter.java View File

23
 
23
 
24
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
24
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
25
 
25
 
26
-@SuppressWarnings("FieldCanBeLocal")
27
 public class Presenter {
26
 public class Presenter {
28
-
29
     private Activity activity;
27
     private Activity activity;
30
     private Options defaultOptions;
28
     private Options defaultOptions;
31
 
29
 
194
     }
192
     }
195
 
193
 
196
     private void applyNavigationBarOptions(NavigationBarOptions options) {
194
     private void applyNavigationBarOptions(NavigationBarOptions options) {
195
+        applyNavigationBarVisibility(options);
197
         setNavigationBarBackgroundColor(options);
196
         setNavigationBarBackgroundColor(options);
198
     }
197
     }
199
 
198
 
200
     private void mergeNavigationBarOptions(NavigationBarOptions options) {
199
     private void mergeNavigationBarOptions(NavigationBarOptions options) {
200
+        mergeNavigationBarVisibility(options);
201
         setNavigationBarBackgroundColor(options);
201
         setNavigationBarBackgroundColor(options);
202
     }
202
     }
203
 
203
 
204
+    private void mergeNavigationBarVisibility(NavigationBarOptions options) {
205
+        if (options.isVisible.hasValue()) applyNavigationBarOptions(options);
206
+    }
207
+
208
+    private void applyNavigationBarVisibility(NavigationBarOptions options) {
209
+        View decorView = activity.getWindow().getDecorView();
210
+        int flags = decorView.getSystemUiVisibility();
211
+        boolean defaultVisibility = (flags & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0;
212
+        int hideNavigationBarFlags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
213
+        if (options.isVisible.get(defaultVisibility)) {
214
+            flags &= ~hideNavigationBarFlags;
215
+        } else {
216
+            flags |= hideNavigationBarFlags;
217
+        }
218
+        decorView.setSystemUiVisibility(flags);
219
+    }
220
+
204
     private void setNavigationBarBackgroundColor(NavigationBarOptions navigationBar) {
221
     private void setNavigationBarBackgroundColor(NavigationBarOptions navigationBar) {
205
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && navigationBar.backgroundColor.canApplyValue()) {
222
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && navigationBar.backgroundColor.canApplyValue()) {
206
             int defaultColor = activity.getWindow().getNavigationBarColor();
223
             int defaultColor = activity.getWindow().getNavigationBarColor();

+ 2
- 3
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ChildController.java View File

64
     @Override
64
     @Override
65
     public void applyOptions(Options options) {
65
     public void applyOptions(Options options) {
66
         super.applyOptions(options);
66
         super.applyOptions(options);
67
-        Options resolvedOptions = resolveCurrentOptions();
68
-        presenter.applyOptions(this, resolvedOptions);
67
+        presenter.applyOptions(this, resolveCurrentOptions());
69
     }
68
     }
70
 
69
 
71
     @Override
70
     @Override
85
         childRegistry.onChildDestroyed(this);
84
         childRegistry.onChildDestroyed(this);
86
     }
85
     }
87
 
86
 
88
-    protected boolean isRoot() {
87
+    boolean isRoot() {
89
         return getParentController() == null &&
88
         return getParentController() == null &&
90
                 !(this instanceof Navigator) &&
89
                 !(this instanceof Navigator) &&
91
                 getView().getParent() != null;
90
                 getView().getParent() != null;

+ 15
- 0
playground/src/screens/OptionsScreen.js View File

1
 const React = require('react');
1
 const React = require('react');
2
 const {Component} = require('react');
2
 const {Component} = require('react');
3
+import {Platform} from 'react-native';
3
 const Root = require('../components/Root');
4
 const Root = require('../components/Root');
4
 const Button = require('../components/Button')
5
 const Button = require('../components/Button')
5
 const Navigation = require('../services/Navigation');
6
 const Navigation = require('../services/Navigation');
29
     };
30
     };
30
   }
31
   }
31
 
32
 
33
+  state = {
34
+    isAndroidNavigationBarVisible: true
35
+  };
36
+
32
   render() {
37
   render() {
33
     return (
38
     return (
34
       <Root componentId={this.props.componentId}>
39
       <Root componentId={this.props.componentId}>
41
         <Button label='Show Yellow Box' testID={SHOW_YELLOW_BOX_BTN} onPress={() => console.warn('Yellow Box')} />
46
         <Button label='Show Yellow Box' testID={SHOW_YELLOW_BOX_BTN} onPress={() => console.warn('Yellow Box')} />
42
         <Button label='StatusBar' onPress={this.statusBarScreen} />
47
         <Button label='StatusBar' onPress={this.statusBarScreen} />
43
         <Button label='Buttons Screen' testID={GOTO_BUTTONS_SCREEN} onPress={this.pushButtonsScreen} />
48
         <Button label='Buttons Screen' testID={GOTO_BUTTONS_SCREEN} onPress={this.pushButtonsScreen} />
49
+        <Button label='Toggle Navigation bar visibility' platform='android' onPress={this.toggleAndroidNavigationBar}/>
44
       </Root>
50
       </Root>
45
     );
51
     );
46
   }
52
   }
65
     }
71
     }
66
   });
72
   });
67
 
73
 
74
+  toggleAndroidNavigationBar = () => {
75
+    this.setState({isAndroidNavigationBarVisible: !this.state.isAndroidNavigationBarVisible});
76
+    Navigation.mergeOptions(this, {
77
+      navigationBar: {
78
+        visible: !this.state.isAndroidNavigationBarVisible
79
+      }
80
+    })
81
+  };
82
+
68
   push = () => Navigation.push(this, {
83
   push = () => Navigation.push(this, {
69
     component: {
84
     component: {
70
       name: Screens.Pushed,
85
       name: Screens.Pushed,