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,7 +1,10 @@
1 1
 package com.reactnativenavigation.parse;
2 2
 
3
+import com.reactnativenavigation.parse.params.Bool;
3 4
 import com.reactnativenavigation.parse.params.Colour;
5
+import com.reactnativenavigation.parse.params.NullBool;
4 6
 import com.reactnativenavigation.parse.params.NullColor;
7
+import com.reactnativenavigation.parse.parsers.BoolParser;
5 8
 import com.reactnativenavigation.parse.parsers.ColorParser;
6 9
 
7 10
 import org.json.JSONObject;
@@ -12,17 +15,21 @@ public class NavigationBarOptions {
12 15
         if (json == null) return result;
13 16
 
14 17
         result.backgroundColor = ColorParser.parse(json, "backgroundColor");
18
+        result.isVisible = BoolParser.parse(json, "visible");
15 19
 
16 20
         return result;
17 21
     }
18 22
 
19 23
     public Colour backgroundColor = new NullColor();
24
+    public Bool isVisible = new NullBool();
20 25
 
21 26
     public void mergeWith(NavigationBarOptions other) {
22 27
         if (other.backgroundColor.hasValue()) backgroundColor = other.backgroundColor;
28
+        if (other.isVisible.hasValue()) isVisible = other.isVisible;
23 29
     }
24 30
 
25 31
     public void mergeWithDefault(NavigationBarOptions defaultOptions) {
26 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,9 +23,7 @@ import com.reactnativenavigation.viewcontrollers.navigator.Navigator;
23 23
 
24 24
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
25 25
 
26
-@SuppressWarnings("FieldCanBeLocal")
27 26
 public class Presenter {
28
-
29 27
     private Activity activity;
30 28
     private Options defaultOptions;
31 29
 
@@ -194,13 +192,32 @@ public class Presenter {
194 192
     }
195 193
 
196 194
     private void applyNavigationBarOptions(NavigationBarOptions options) {
195
+        applyNavigationBarVisibility(options);
197 196
         setNavigationBarBackgroundColor(options);
198 197
     }
199 198
 
200 199
     private void mergeNavigationBarOptions(NavigationBarOptions options) {
200
+        mergeNavigationBarVisibility(options);
201 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 221
     private void setNavigationBarBackgroundColor(NavigationBarOptions navigationBar) {
205 222
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && navigationBar.backgroundColor.canApplyValue()) {
206 223
             int defaultColor = activity.getWindow().getNavigationBarColor();

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

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

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

@@ -1,5 +1,6 @@
1 1
 const React = require('react');
2 2
 const {Component} = require('react');
3
+import {Platform} from 'react-native';
3 4
 const Root = require('../components/Root');
4 5
 const Button = require('../components/Button')
5 6
 const Navigation = require('../services/Navigation');
@@ -29,6 +30,10 @@ class Options extends Component {
29 30
     };
30 31
   }
31 32
 
33
+  state = {
34
+    isAndroidNavigationBarVisible: true
35
+  };
36
+
32 37
   render() {
33 38
     return (
34 39
       <Root componentId={this.props.componentId}>
@@ -41,6 +46,7 @@ class Options extends Component {
41 46
         <Button label='Show Yellow Box' testID={SHOW_YELLOW_BOX_BTN} onPress={() => console.warn('Yellow Box')} />
42 47
         <Button label='StatusBar' onPress={this.statusBarScreen} />
43 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 50
       </Root>
45 51
     );
46 52
   }
@@ -65,6 +71,15 @@ class Options extends Component {
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 83
   push = () => Navigation.push(this, {
69 84
     component: {
70 85
       name: Screens.Pushed,