Bläddra i källkod

Hide back button in mergeOptions (#5826)

This commit fixes hiding the back button with `backButton.visible: false` in mergeOptions. It didn't work on Android.
Guy Carmeli 5 år sedan
förälder
incheckning
3f17dc4a82
No account linked to committer's email address

+ 5
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/BackButton.java Visa fil

@@ -65,4 +65,9 @@ public class BackButton extends Button {
65 65
         visible = new Bool(true);
66 66
         hasValue = true;
67 67
     }
68
+
69
+    public void setHidden() {
70
+        visible = new Bool(false);
71
+        hasValue = true;
72
+    }
68 73
 }

+ 2
- 1
lib/android/app/src/main/java/com/reactnativenavigation/parse/LayoutFactory.java Visa fil

@@ -20,6 +20,7 @@ import com.reactnativenavigation.viewcontrollers.ComponentViewController;
20 20
 import com.reactnativenavigation.viewcontrollers.ViewController;
21 21
 import com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsAttacher;
22 22
 import com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsController;
23
+import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
23 24
 import com.reactnativenavigation.viewcontrollers.externalcomponent.ExternalComponentCreator;
24 25
 import com.reactnativenavigation.viewcontrollers.externalcomponent.ExternalComponentViewController;
25 26
 import com.reactnativenavigation.viewcontrollers.sidemenu.SideMenuController;
@@ -186,7 +187,7 @@ public class LayoutFactory {
186 187
                         new TitleBarReactViewCreator(reactInstanceManager),
187 188
                         new TopBarBackgroundViewCreator(reactInstanceManager),
188 189
                         new TitleBarButtonCreator(reactInstanceManager),
189
-                        new ImageLoader(),
190
+                        new NavigationIconResolver(activity, new ImageLoader()),
190 191
                         new RenderChecker(),
191 192
                         defaultOptions
192 193
                 ))

+ 11
- 7
lib/android/app/src/main/java/com/reactnativenavigation/presentation/StackPresenter.java Visa fil

@@ -21,7 +21,6 @@ import com.reactnativenavigation.parse.params.Button;
21 21
 import com.reactnativenavigation.parse.params.Colour;
22 22
 import com.reactnativenavigation.utils.ButtonPresenter;
23 23
 import com.reactnativenavigation.utils.CollectionUtils;
24
-import com.reactnativenavigation.utils.ImageLoader;
25 24
 import com.reactnativenavigation.utils.ObjectUtils;
26 25
 import com.reactnativenavigation.utils.StatusBarUtils;
27 26
 import com.reactnativenavigation.utils.UiUtils;
@@ -65,7 +64,6 @@ public class StackPresenter {
65 64
     private TopBarController topBarController;
66 65
     private final TitleBarReactViewCreator titleViewCreator;
67 66
     private TitleBarButtonController.OnClickListener onClickListener;
68
-    private final ImageLoader imageLoader;
69 67
     private final RenderChecker renderChecker;
70 68
     private final TopBarBackgroundViewCreator topBarBackgroundViewCreator;
71 69
     private final ReactViewCreator buttonCreator;
@@ -76,19 +74,20 @@ public class StackPresenter {
76 74
     private Map<View, TopBarBackgroundViewController> backgroundControllers = new HashMap();
77 75
     private Map<View, Map<String, TitleBarButtonController>> componentRightButtons = new HashMap();
78 76
     private Map<View, Map<String, TitleBarButtonController>> componentLeftButtons = new HashMap();
77
+    private NavigationIconResolver iconResolver;
79 78
 
80 79
     public StackPresenter(Activity activity,
81 80
                           TitleBarReactViewCreator titleViewCreator,
82 81
                           TopBarBackgroundViewCreator topBarBackgroundViewCreator,
83 82
                           ReactViewCreator buttonCreator,
84
-                          ImageLoader imageLoader,
83
+                          NavigationIconResolver iconResolver,
85 84
                           RenderChecker renderChecker,
86 85
                           Options defaultOptions) {
87 86
         this.activity = activity;
88 87
         this.titleViewCreator = titleViewCreator;
89 88
         this.topBarBackgroundViewCreator = topBarBackgroundViewCreator;
90 89
         this.buttonCreator = buttonCreator;
91
-        this.imageLoader = imageLoader;
90
+        this.iconResolver = iconResolver;
92 91
         this.renderChecker = renderChecker;
93 92
         this.defaultOptions = defaultOptions;
94 93
         defaultTitleFontSize = UiUtils.dpToSp(activity, 18);
@@ -311,8 +310,7 @@ public class StackPresenter {
311 310
 
312 311
     private TitleBarButtonController createButtonController(Button button) {
313 312
         TitleBarButtonController controller = new TitleBarButtonController(activity,
314
-                new NavigationIconResolver(activity, imageLoader),
315
-                imageLoader,
313
+                iconResolver,
316 314
                 new ButtonPresenter(topBar.getTitleBar(), button),
317 315
                 button,
318 316
                 buttonCreator,
@@ -379,7 +377,13 @@ public class StackPresenter {
379 377
             }
380 378
         }
381 379
         if (buttons.left != null) topBar.setLeftButtons(leftButtonControllers);
382
-        if (buttons.back.hasValue()) topBar.setBackButton(createButtonController(buttons.back));
380
+        if (buttons.back.hasValue()) {
381
+            if (buttons.back.visible.isFalse()) {
382
+                topBar.clearLeftButtons();
383
+            } else {
384
+                topBar.setBackButton(createButtonController(buttons.back));
385
+            }
386
+        }
383 387
 
384 388
         if (options.rightButtonColor.hasValue()) topBar.setOverflowButtonColor(options.rightButtonColor.get());
385 389
     }

+ 9
- 0
lib/android/app/src/main/java/com/reactnativenavigation/utils/ImageLoader.java Visa fil

@@ -1,5 +1,6 @@
1 1
 package com.reactnativenavigation.utils;
2 2
 
3
+import android.app.Activity;
3 4
 import android.content.Context;
4 5
 import android.graphics.Bitmap;
5 6
 import android.graphics.BitmapFactory;
@@ -7,9 +8,11 @@ import android.graphics.drawable.BitmapDrawable;
7 8
 import android.graphics.drawable.Drawable;
8 9
 import android.net.Uri;
9 10
 import android.os.StrictMode;
11
+import android.view.View;
10 12
 
11 13
 import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
12 14
 import com.reactnativenavigation.NavigationApplication;
15
+import com.reactnativenavigation.R;
13 16
 
14 17
 import java.io.FileNotFoundException;
15 18
 import java.io.IOException;
@@ -20,6 +23,7 @@ import java.util.List;
20 23
 
21 24
 import androidx.annotation.NonNull;
22 25
 import androidx.annotation.Nullable;
26
+import androidx.core.content.ContextCompat;
23 27
 
24 28
 public class ImageLoader {
25 29
 
@@ -33,6 +37,11 @@ public class ImageLoader {
33 37
 
34 38
     private static final String FILE_SCHEME = "file";
35 39
 
40
+    public Drawable getBackButtonIcon(Activity context) {
41
+        boolean isRTL = context.getWindow().getDecorView().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
42
+        return ContextCompat.getDrawable(context, isRTL ? R.drawable.ic_arrow_back_black_rtl_24dp : R.drawable.ic_arrow_back_black_24dp);
43
+    }
44
+
36 45
     @Nullable
37 46
     public Drawable loadIcon(Context context, @Nullable String uri) {
38 47
         if (uri == null) return null;

+ 3
- 9
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/TitleBarButtonController.java Visa fil

@@ -22,7 +22,6 @@ import com.reactnativenavigation.utils.ViewUtils;
22 22
 import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
23 23
 import com.reactnativenavigation.views.titlebar.TitleBarReactButtonView;
24 24
 
25
-import java.util.Collections;
26 25
 import java.util.List;
27 26
 
28 27
 import androidx.annotation.NonNull;
@@ -36,7 +35,6 @@ public class TitleBarButtonController extends ViewController<TitleBarReactButton
36 35
     }
37 36
 
38 37
     private final NavigationIconResolver navigationIconResolver;
39
-    private final ImageLoader imageLoader;
40 38
     private ButtonPresenter optionsPresenter;
41 39
     private final Button button;
42 40
     private final ReactViewCreator viewCreator;
@@ -54,14 +52,12 @@ public class TitleBarButtonController extends ViewController<TitleBarReactButton
54 52
 
55 53
     public TitleBarButtonController(Activity activity,
56 54
                                     NavigationIconResolver navigationIconResolver,
57
-                                    ImageLoader imageLoader,
58 55
                                     ButtonPresenter optionsPresenter,
59 56
                                     Button button,
60 57
                                     ReactViewCreator viewCreator,
61 58
                                     OnClickListener onClickListener) {
62 59
         super(activity, button.id, new YellowBoxDelegate(), new Options());
63 60
         this.navigationIconResolver = navigationIconResolver;
64
-        this.imageLoader = imageLoader;
65 61
         this.optionsPresenter = optionsPresenter;
66 62
         this.button = button;
67 63
         this.viewCreator = viewCreator;
@@ -104,8 +100,7 @@ public class TitleBarButtonController extends ViewController<TitleBarReactButton
104 100
     }
105 101
 
106 102
     public void applyNavigationIcon(Toolbar toolbar) {
107
-        Integer direction = getActivity().getWindow().getDecorView().getLayoutDirection();
108
-        navigationIconResolver.resolve(button, direction, icon -> {
103
+        navigationIconResolver.resolve(button, icon -> {
109 104
             setIconColor(icon);
110 105
             toolbar.setNavigationOnClickListener(view -> onPressListener.onPress(button.id));
111 106
             toolbar.setNavigationIcon(icon);
@@ -134,8 +129,7 @@ public class TitleBarButtonController extends ViewController<TitleBarReactButton
134 129
             if (button.hasIcon()) {
135 130
                 loadIcon(new ImageLoadingListenerAdapter() {
136 131
                     @Override
137
-                    public void onComplete(@NonNull List<Drawable> icons) {
138
-                        Drawable icon = icons.get(0);
132
+                    public void onComplete(@NonNull Drawable icon) {
139 133
                         TitleBarButtonController.this.icon = icon;
140 134
                         setIconColor(icon);
141 135
                         menuItem.setIcon(icon);
@@ -151,7 +145,7 @@ public class TitleBarButtonController extends ViewController<TitleBarReactButton
151 145
     }
152 146
 
153 147
     private void loadIcon(ImageLoader.ImagesLoadingListener callback) {
154
-        imageLoader.loadIcons(getActivity(), Collections.singletonList(button.icon.get()), callback);
148
+        navigationIconResolver.resolve(button, callback::onComplete);
155 149
     }
156 150
 
157 151
     private void setIconColor(Drawable icon) {

+ 8
- 11
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/button/NavigationIconResolver.java Visa fil

@@ -1,31 +1,29 @@
1 1
 package com.reactnativenavigation.viewcontrollers.button;
2 2
 
3
-import android.content.Context;
3
+import android.app.Activity;
4 4
 import android.graphics.drawable.Drawable;
5
-import androidx.annotation.NonNull;
6
-import androidx.core.content.ContextCompat;
7 5
 import android.util.Log;
8
-import android.view.View;
9 6
 
10
-import com.reactnativenavigation.R;
11 7
 import com.reactnativenavigation.parse.params.Button;
12 8
 import com.reactnativenavigation.react.Constants;
13 9
 import com.reactnativenavigation.utils.Functions.Func1;
14 10
 import com.reactnativenavigation.utils.ImageLoader;
15 11
 import com.reactnativenavigation.utils.ImageLoadingListenerAdapter;
16 12
 
13
+import androidx.annotation.NonNull;
14
+
17 15
 public class NavigationIconResolver {
18 16
 
19
-    private Context context;
17
+    private Activity context;
20 18
     private ImageLoader imageLoader;
21 19
 
22
-    public NavigationIconResolver(Context context, ImageLoader imageLoader) {
20
+    public NavigationIconResolver(Activity context, ImageLoader imageLoader) {
23 21
         this.context = context;
24 22
         this.imageLoader = imageLoader;
25 23
     }
26 24
 
27
-    public void resolve(Button button, Integer direction, Func1<Drawable> onSuccess) {
28
-        if (button.icon.hasValue()) {
25
+    public void resolve(Button button, Func1<Drawable> onSuccess) {
26
+        if (button.hasIcon()) {
29 27
             imageLoader.loadIcon(context, button.icon.get(), new ImageLoadingListenerAdapter() {
30 28
                 @Override
31 29
                 public void onComplete(@NonNull Drawable icon) {
@@ -38,8 +36,7 @@ public class NavigationIconResolver {
38 36
                 }
39 37
             });
40 38
         } else if (Constants.BACK_BUTTON_ID.equals(button.id)) {
41
-            Boolean isRTL = direction == View.LAYOUT_DIRECTION_RTL;
42
-            onSuccess.run(ContextCompat.getDrawable(context, isRTL ? R.drawable.ic_arrow_back_black_rtl_24dp : R.drawable.ic_arrow_back_black_24dp));
39
+            onSuccess.run(imageLoader.getBackButtonIcon(context));
43 40
         } else {
44 41
             Log.w("RNN", "Left button needs to have an icon");
45 42
         }

+ 2
- 1
lib/android/app/src/test/java/com/reactnativenavigation/TestUtils.java Visa fil

@@ -17,6 +17,7 @@ import com.reactnativenavigation.utils.ImageLoader;
17 17
 import com.reactnativenavigation.utils.UiUtils;
18 18
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
19 19
 import com.reactnativenavigation.viewcontrollers.ViewController;
20
+import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
20 21
 import com.reactnativenavigation.viewcontrollers.stack.StackControllerBuilder;
21 22
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
22 23
 import com.reactnativenavigation.views.StackLayout;
@@ -38,7 +39,7 @@ public class TestUtils {
38 39
                 .setId("stack")
39 40
                 .setChildRegistry(new ChildControllersRegistry())
40 41
                 .setTopBarController(topBarController)
41
-                .setStackPresenter(new StackPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), new TopBarButtonCreatorMock(), new ImageLoader(), new RenderChecker(), new Options()))
42
+                .setStackPresenter(new StackPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), new TopBarButtonCreatorMock(), new NavigationIconResolver(activity, new ImageLoader()), new RenderChecker(), new Options()))
42 43
                 .setInitialOptions(new Options());
43 44
     }
44 45
 

+ 30
- 0
lib/android/app/src/test/java/com/reactnativenavigation/mocks/BackDrawable.java Visa fil

@@ -0,0 +1,30 @@
1
+package com.reactnativenavigation.mocks;
2
+
3
+import android.graphics.Canvas;
4
+import android.graphics.ColorFilter;
5
+import android.graphics.drawable.Drawable;
6
+
7
+import androidx.annotation.NonNull;
8
+import androidx.annotation.Nullable;
9
+
10
+public class BackDrawable extends Drawable {
11
+    @Override
12
+    public void draw(@NonNull Canvas canvas) {
13
+
14
+    }
15
+
16
+    @Override
17
+    public void setAlpha(int alpha) {
18
+
19
+    }
20
+
21
+    @Override
22
+    public void setColorFilter(@Nullable ColorFilter colorFilter) {
23
+
24
+    }
25
+
26
+    @Override
27
+    public int getOpacity() {
28
+        return 0;
29
+    }
30
+}

+ 7
- 5
lib/android/app/src/test/java/com/reactnativenavigation/mocks/ImageLoaderMock.java Visa fil

@@ -3,7 +3,6 @@ package com.reactnativenavigation.mocks;
3 3
 import android.graphics.Canvas;
4 4
 import android.graphics.ColorFilter;
5 5
 import android.graphics.drawable.Drawable;
6
-import androidx.annotation.NonNull;
7 6
 
8 7
 import com.reactnativenavigation.utils.ImageLoader;
9 8
 
@@ -13,6 +12,8 @@ import java.util.Collection;
13 12
 import java.util.Collections;
14 13
 import java.util.List;
15 14
 
15
+import androidx.annotation.NonNull;
16
+
16 17
 import static org.mockito.ArgumentMatchers.any;
17 18
 import static org.mockito.Mockito.doAnswer;
18 19
 
@@ -39,22 +40,23 @@ public class ImageLoaderMock {
39 40
         }
40 41
     };
41 42
 
43
+    private static Drawable backIcon = new BackDrawable();
44
+
42 45
     public static ImageLoader mock() {
43 46
         ImageLoader imageLoader = Mockito.mock(ImageLoader.class);
44
-        doAnswer(
45
-                invocation -> {
47
+        doAnswer(invocation -> {
46 48
                     int urlCount = ((Collection) invocation.getArguments()[1]).size();
47 49
                     List<Drawable> drawables = Collections.nCopies(urlCount, mockDrawable);
48 50
                     ((ImageLoader.ImagesLoadingListener) invocation.getArguments()[2]).onComplete(drawables);
49 51
                     return null;
50 52
                 }
51 53
         ).when(imageLoader).loadIcons(any(), any(), any());
52
-        doAnswer(
53
-                invocation -> {
54
+        doAnswer(invocation -> {
54 55
                     ((ImageLoader.ImagesLoadingListener) invocation.getArguments()[2]).onComplete(mockDrawable);
55 56
                     return null;
56 57
                 }
57 58
         ).when(imageLoader).loadIcon(any(), any(), any());
59
+        doAnswer(invocation -> backIcon).when(imageLoader).getBackButtonIcon(any());
58 60
         return imageLoader;
59 61
     }
60 62
 }

+ 3
- 3
lib/android/app/src/test/java/com/reactnativenavigation/utils/TitleBarHelper.java Visa fil

@@ -1,8 +1,6 @@
1 1
 package com.reactnativenavigation.utils;
2 2
 
3 3
 import android.app.Activity;
4
-import androidx.appcompat.view.menu.ActionMenuItemView;
5
-import androidx.appcompat.widget.Toolbar;
6 4
 
7 5
 import com.reactnativenavigation.mocks.ImageLoaderMock;
8 6
 import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
@@ -13,6 +11,9 @@ import com.reactnativenavigation.viewcontrollers.TitleBarButtonController;
13 11
 import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
14 12
 import com.reactnativenavigation.views.titlebar.TitleBar;
15 13
 
14
+import androidx.appcompat.view.menu.ActionMenuItemView;
15
+import androidx.appcompat.widget.Toolbar;
16
+
16 17
 public class TitleBarHelper {
17 18
     public static ActionMenuItemView getRightButton(Toolbar toolbar, int index) {
18 19
         return (ActionMenuItemView) ViewUtils.findChildrenByClassRecursive(toolbar, ActionMenuItemView.class).get(toolbar.getMenu().size() - index - 1);
@@ -45,7 +46,6 @@ public class TitleBarHelper {
45 46
     public static TitleBarButtonController createButtonController(Activity activity, TitleBar titleBar, Button button) {
46 47
         return new TitleBarButtonController(activity,
47 48
                 new NavigationIconResolver(activity, ImageLoaderMock.mock()),
48
-                ImageLoaderMock.mock(),
49 49
                 new ButtonPresenter(titleBar, button),
50 50
                 button,
51 51
                 new TopBarButtonCreatorMock(),

+ 51
- 28
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/StackPresenterTest.java Visa fil

@@ -5,10 +5,10 @@ import android.content.Context;
5 5
 import android.graphics.Typeface;
6 6
 import android.view.Gravity;
7 7
 import android.view.View;
8
-import android.view.ViewGroup;
9 8
 
10 9
 import com.reactnativenavigation.BaseTest;
11 10
 import com.reactnativenavigation.TestUtils;
11
+import com.reactnativenavigation.mocks.BackDrawable;
12 12
 import com.reactnativenavigation.mocks.ImageLoaderMock;
13 13
 import com.reactnativenavigation.mocks.Mocks;
14 14
 import com.reactnativenavigation.mocks.SimpleViewController;
@@ -29,7 +29,10 @@ import com.reactnativenavigation.parse.params.Number;
29 29
 import com.reactnativenavigation.parse.params.Text;
30 30
 import com.reactnativenavigation.presentation.RenderChecker;
31 31
 import com.reactnativenavigation.presentation.StackPresenter;
32
+import com.reactnativenavigation.utils.CommandListenerAdapter;
32 33
 import com.reactnativenavigation.utils.TitleBarHelper;
34
+import com.reactnativenavigation.utils.UiUtils;
35
+import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
33 36
 import com.reactnativenavigation.viewcontrollers.stack.StackController;
34 37
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
35 38
 import com.reactnativenavigation.views.StackLayout;
@@ -39,6 +42,8 @@ import com.reactnativenavigation.views.topbar.TopBar;
39 42
 import org.json.JSONObject;
40 43
 import org.junit.Test;
41 44
 import org.mockito.ArgumentCaptor;
45
+import org.robolectric.annotation.LooperMode;
46
+import org.robolectric.shadows.ShadowLooper;
42 47
 
43 48
 import java.util.ArrayList;
44 49
 import java.util.Collection;
@@ -47,6 +52,7 @@ import java.util.List;
47 52
 
48 53
 import androidx.appcompat.widget.ActionMenuView;
49 54
 import androidx.appcompat.widget.Toolbar;
55
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
50 56
 
51 57
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
52 58
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
@@ -62,6 +68,7 @@ import static org.mockito.Mockito.times;
62 68
 import static org.mockito.Mockito.verify;
63 69
 import static org.mockito.Mockito.when;
64 70
 
71
+@LooperMode(LooperMode.Mode.PAUSED)
65 72
 public class StackPresenterTest extends BaseTest {
66 73
 
67 74
     private static final Options EMPTY_OPTIONS = new Options();
@@ -78,6 +85,8 @@ public class StackPresenterTest extends BaseTest {
78 85
     private Button componentBtn1 = TitleBarHelper.reactViewButton("btn1_");
79 86
     private Button componentBtn2 = TitleBarHelper.reactViewButton("btn2_");
80 87
     private TopBarController topBarController;
88
+    private ChildControllersRegistry childRegistry;
89
+    private NavigationIconResolver iconResolver;
81 90
 
82 91
     @Override
83 92
     public void beforeEach() {
@@ -89,24 +98,19 @@ public class StackPresenterTest extends BaseTest {
89 98
             }
90 99
         };
91 100
         renderChecker = spy(new RenderChecker());
92
-        uut = spy(new StackPresenter(activity, titleViewCreator, new TopBarBackgroundViewCreatorMock(), new TopBarButtonCreatorMock(), ImageLoaderMock.mock(), renderChecker, new Options()));
93
-        topBar = mockTopBar();
94
-        topBarController = spy(new TopBarController() {
95
-            @Override
96
-            protected TopBar createTopBar(Context context, StackLayout stackLayout) {
97
-                return topBar;
98
-            }
99
-        });
101
+        iconResolver = new NavigationIconResolver(activity, ImageLoaderMock.mock());
102
+        uut = spy(new StackPresenter(activity, titleViewCreator, new TopBarBackgroundViewCreatorMock(), new TopBarButtonCreatorMock(), iconResolver, renderChecker, new Options()));
103
+        createTopBarController();
100 104
 
101 105
         parent = TestUtils.newStackController(activity)
102 106
                 .setTopBarController(topBarController)
103 107
                 .setStackPresenter(uut)
104 108
                 .build();
105
-        parent.ensureViewIsCreated();
106 109
 
107
-        ChildControllersRegistry childRegistry = new ChildControllersRegistry();
110
+        childRegistry = new ChildControllersRegistry();
108 111
         child = spy(new SimpleViewController(activity, childRegistry, "child1", Options.EMPTY));
109 112
         otherChild = spy(new SimpleViewController(activity, childRegistry, "child1", Options.EMPTY));
113
+        activity.setContentView(parent.getView());
110 114
     }
111 115
 
112 116
     @Test
@@ -114,13 +118,13 @@ public class StackPresenterTest extends BaseTest {
114 118
         Options o1 = new Options();
115 119
         o1.topBar.title.component = component(Alignment.Default);
116 120
         o1.topBar.background.component = component(Alignment.Default);
117
-        o1.topBar.buttons.right = new ArrayList(Collections.singletonList(componentBtn1));
121
+        o1.topBar.buttons.right = new ArrayList<>(Collections.singletonList(componentBtn1));
118 122
         uut.applyChildOptions(o1, parent, child);
119 123
 
120 124
         uut.isRendered(child.getView());
121 125
         ArgumentCaptor<Collection<ViewController>> controllers = ArgumentCaptor.forClass(Collection.class);
122 126
         verify(renderChecker).areRendered(controllers.capture());
123
-        ArrayList<ViewController> items = new ArrayList(controllers.getValue());
127
+        ArrayList<ViewController> items = new ArrayList<>(controllers.getValue());
124 128
         assertThat(items.contains(uut.getComponentButtons(child.getView()).get(0))).isTrue();
125 129
         assertThat(items.contains(uut.getTitleComponents().get(child.getView()))).isTrue();
126 130
         assertThat(items.contains(uut.getBackgroundComponents().get(child.getView()))).isTrue();
@@ -250,6 +254,27 @@ public class StackPresenterTest extends BaseTest {
250 254
         assertThat(initialButtons.get(1).isDestroyed()).isTrue();
251 255
     }
252 256
 
257
+    @Test
258
+    public void mergeButtons_backButtonIsRemovedIfVisibleFalse() {
259
+        ViewController pushedChild = spy(new SimpleViewController(activity, childRegistry, "child2", new Options()));
260
+        disablePushAnimation(child, pushedChild);
261
+        parent.push(child, new CommandListenerAdapter());
262
+
263
+        assertThat(topBar.getTitleBar().getNavigationIcon()).isNull();
264
+
265
+        parent.push(pushedChild, new CommandListenerAdapter());
266
+        ShadowLooper.idleMainLooper();
267
+        verify(pushedChild).onViewAppeared();
268
+        assertThat(topBar.getTitleBar().getNavigationIcon()).isInstanceOf(BackDrawable.class);
269
+
270
+        Options backButtonHidden = new Options();
271
+        backButtonHidden.topBar.buttons.back.setHidden();
272
+        uut.mergeChildOptions(backButtonHidden, backButtonHidden, parent, child);
273
+
274
+        ShadowLooper.idleMainLooper();
275
+        assertThat(topBar.getTitleBar().getNavigationIcon()).isNull();
276
+    }
277
+
253 278
     @Test
254 279
     public void mergeTopBarOptions() {
255 280
         Options options = new Options();
@@ -302,20 +327,6 @@ public class StackPresenterTest extends BaseTest {
302 327
         verify(topBar, times(1)).setTopTabsVisible(anyBoolean());
303 328
     }
304 329
 
305
-    @Test
306
-    public void mergeTopTabOptions() {
307
-        Options options = new Options();
308
-        uut.mergeChildOptions(options, EMPTY_OPTIONS, parent, child);
309
-
310
-        verify(topBar, times(0)).setTopTabFontFamily(anyInt(), any());
311
-
312
-        options.topTabOptions.tabIndex = 1;
313
-        options.topTabOptions.fontFamily = Typeface.DEFAULT_BOLD;
314
-        uut.mergeChildOptions(options, EMPTY_OPTIONS, parent, child);
315
-
316
-        verify(topBar, times(1)).setTopTabFontFamily(1, Typeface.DEFAULT_BOLD);
317
-    }
318
-
319 330
     @Test
320 331
     public void applyInitialChildLayoutOptions() {
321 332
         Options options = new Options();
@@ -571,10 +582,22 @@ public class StackPresenterTest extends BaseTest {
571 582
         toolbar.addView(new ActionMenuView(activity));
572 583
         when(topBar.getTitleBar()).then(invocation -> toolbar);
573 584
         when(topBar.getContext()).then(invocation -> activity);
574
-        when(topBar.getLayoutParams()).thenReturn(new ViewGroup.MarginLayoutParams(MATCH_PARENT, WRAP_CONTENT));
585
+        when(topBar.dispatchApplyWindowInsets(any())).then(invocation -> invocation.getArguments()[0]);
586
+        when(topBar.getLayoutParams()).thenReturn(new CoordinatorLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
575 587
         return topBar;
576 588
     }
577 589
 
590
+    private void createTopBarController() {
591
+        topBarController = spy(new TopBarController() {
592
+            @Override
593
+            protected TopBar createTopBar(Context context, StackLayout stackLayout) {
594
+                topBar = spy(super.createTopBar(context, stackLayout));
595
+                topBar.layout(0, 0, 1000, UiUtils.getTopBarHeight(activity));
596
+                return topBar;
597
+            }
598
+        });
599
+    }
600
+
578 601
     private Component component(Alignment alignment) {
579 602
         Component component = new Component();
580 603
         component.name = new Text("myComp");

+ 2
- 2
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TopBarButtonControllerTest.java Visa fil

@@ -51,7 +51,7 @@ public class TopBarButtonControllerTest extends BaseTest {
51 51
         getTitleBar().layout(0, 0, 1080, 200);
52 52
 
53 53
         optionsPresenter = spy(new ButtonPresenter(getTitleBar(), button));
54
-        uut = new TitleBarButtonController(activity, new NavigationIconResolver(activity, ImageLoaderMock.mock()), ImageLoaderMock.mock(), optionsPresenter, button, buttonCreatorMock, (buttonId) -> {});
54
+        uut = new TitleBarButtonController(activity, new NavigationIconResolver(activity, ImageLoaderMock.mock()), optionsPresenter, button, buttonCreatorMock, (buttonId) -> {});
55 55
 
56 56
         stackController.ensureViewIsCreated();
57 57
     }
@@ -87,7 +87,7 @@ public class TopBarButtonControllerTest extends BaseTest {
87 87
         button.disabledColor = new Colour(Color.BLACK);
88 88
         uut.addToMenu(getTitleBar(), 0);
89 89
 
90
-        verify(optionsPresenter, times(1)).tint(any(), eq(Color.BLACK));
90
+        verify(optionsPresenter).tint(any(), eq(Color.BLACK));
91 91
     }
92 92
 
93 93
     @Test

+ 6
- 8
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/button/NavigationIconResolverTest.java Visa fil

@@ -1,11 +1,11 @@
1 1
 package com.reactnativenavigation.viewcontrollers.button;
2 2
 
3
-import android.content.Context;
3
+import android.app.Activity;
4 4
 import android.graphics.Color;
5 5
 import android.graphics.drawable.Drawable;
6
-import android.view.View;
7 6
 
8 7
 import com.reactnativenavigation.BaseTest;
8
+import com.reactnativenavigation.mocks.BackDrawable;
9 9
 import com.reactnativenavigation.mocks.ImageLoaderMock;
10 10
 import com.reactnativenavigation.parse.params.Button;
11 11
 import com.reactnativenavigation.parse.params.Colour;
@@ -20,13 +20,12 @@ import static org.mockito.ArgumentMatchers.any;
20 20
 import static org.mockito.ArgumentMatchers.eq;
21 21
 import static org.mockito.Mockito.spy;
22 22
 import static org.mockito.Mockito.verify;
23
-import static org.mockito.Mockito.verifyZeroInteractions;
24 23
 
25 24
 public class NavigationIconResolverTest extends BaseTest {
26 25
     private static final String ICON_URI = "someIconUri";
27 26
     private NavigationIconResolver uut;
28 27
     private ImageLoader imageLoader;
29
-    private Context context;
28
+    private Activity context;
30 29
 
31 30
     @Override
32 31
     public void beforeEach() {
@@ -43,7 +42,7 @@ public class NavigationIconResolverTest extends BaseTest {
43 42
 
44 43
             }
45 44
         });
46
-        uut.resolve(iconButton(), View.LAYOUT_DIRECTION_LTR, onSuccess);
45
+        uut.resolve(iconButton(), onSuccess);
47 46
         verify(imageLoader).loadIcon(eq(context), eq(ICON_URI), any());
48 47
         verify(onSuccess).run(any(Drawable.class));
49 48
     }
@@ -56,9 +55,8 @@ public class NavigationIconResolverTest extends BaseTest {
56 55
 
57 56
             }
58 57
         });
59
-        uut.resolve(backButton(), View.LAYOUT_DIRECTION_LTR, onSuccess);
60
-        verifyZeroInteractions(imageLoader);
61
-        verify(onSuccess).run(any());
58
+        uut.resolve(backButton(), onSuccess);
59
+        verify(onSuccess).run(any(BackDrawable.class));
62 60
     }
63 61
 
64 62
     private Button iconButton() {

+ 2
- 1
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/StackControllerTest.java Visa fil

@@ -32,6 +32,7 @@ import com.reactnativenavigation.utils.ViewUtils;
32 32
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
33 33
 import com.reactnativenavigation.viewcontrollers.ParentController;
34 34
 import com.reactnativenavigation.viewcontrollers.ViewController;
35
+import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
35 36
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
36 37
 import com.reactnativenavigation.views.StackLayout;
37 38
 import com.reactnativenavigation.views.element.ElementTransitionManager;
@@ -95,7 +96,7 @@ public class StackControllerTest extends BaseTest {
95 96
         StatusBarUtils.saveStatusBarHeight(63);
96 97
         animator = spy(new NavigationAnimator(activity, Mockito.mock(ElementTransitionManager.class)));
97 98
         childRegistry = new ChildControllersRegistry();
98
-        presenter = spy(new StackPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), new TopBarButtonCreatorMock(), ImageLoaderMock.mock(), new RenderChecker(), new Options()));
99
+        presenter = spy(new StackPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), new TopBarButtonCreatorMock(), new NavigationIconResolver(activity, ImageLoaderMock.mock()), new RenderChecker(), new Options()));
99 100
         child1 = spy(new SimpleViewController(activity, childRegistry, "child1", new Options()));
100 101
         child1a = spy(new SimpleViewController(activity, childRegistry, "child1", new Options()));
101 102
         child2 = spy(new SimpleViewController(activity, childRegistry, "child2", new Options()));