Skip to content

Commit

Permalink
Hide back button in mergeOptions (#5826)
Browse files Browse the repository at this point in the history
This commit fixes hiding the back button with `backButton.visible: false` in mergeOptions. It didn't work on Android.
  • Loading branch information
guyca authored Jan 5, 2020
1 parent e3f5b49 commit 3f17dc4
Show file tree
Hide file tree
Showing 14 changed files with 141 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,9 @@ public void setVisible() {
visible = new Bool(true);
hasValue = true;
}

public void setHidden() {
visible = new Bool(false);
hasValue = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.reactnativenavigation.viewcontrollers.ViewController;
import com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsAttacher;
import com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsController;
import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
import com.reactnativenavigation.viewcontrollers.externalcomponent.ExternalComponentCreator;
import com.reactnativenavigation.viewcontrollers.externalcomponent.ExternalComponentViewController;
import com.reactnativenavigation.viewcontrollers.sidemenu.SideMenuController;
Expand Down Expand Up @@ -186,7 +187,7 @@ private ViewController createStack(LayoutNode node) {
new TitleBarReactViewCreator(reactInstanceManager),
new TopBarBackgroundViewCreator(reactInstanceManager),
new TitleBarButtonCreator(reactInstanceManager),
new ImageLoader(),
new NavigationIconResolver(activity, new ImageLoader()),
new RenderChecker(),
defaultOptions
))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import com.reactnativenavigation.parse.params.Colour;
import com.reactnativenavigation.utils.ButtonPresenter;
import com.reactnativenavigation.utils.CollectionUtils;
import com.reactnativenavigation.utils.ImageLoader;
import com.reactnativenavigation.utils.ObjectUtils;
import com.reactnativenavigation.utils.StatusBarUtils;
import com.reactnativenavigation.utils.UiUtils;
Expand Down Expand Up @@ -65,7 +64,6 @@ public class StackPresenter {
private TopBarController topBarController;
private final TitleBarReactViewCreator titleViewCreator;
private TitleBarButtonController.OnClickListener onClickListener;
private final ImageLoader imageLoader;
private final RenderChecker renderChecker;
private final TopBarBackgroundViewCreator topBarBackgroundViewCreator;
private final ReactViewCreator buttonCreator;
Expand All @@ -76,19 +74,20 @@ public class StackPresenter {
private Map<View, TopBarBackgroundViewController> backgroundControllers = new HashMap();
private Map<View, Map<String, TitleBarButtonController>> componentRightButtons = new HashMap();
private Map<View, Map<String, TitleBarButtonController>> componentLeftButtons = new HashMap();
private NavigationIconResolver iconResolver;

public StackPresenter(Activity activity,
TitleBarReactViewCreator titleViewCreator,
TopBarBackgroundViewCreator topBarBackgroundViewCreator,
ReactViewCreator buttonCreator,
ImageLoader imageLoader,
NavigationIconResolver iconResolver,
RenderChecker renderChecker,
Options defaultOptions) {
this.activity = activity;
this.titleViewCreator = titleViewCreator;
this.topBarBackgroundViewCreator = topBarBackgroundViewCreator;
this.buttonCreator = buttonCreator;
this.imageLoader = imageLoader;
this.iconResolver = iconResolver;
this.renderChecker = renderChecker;
this.defaultOptions = defaultOptions;
defaultTitleFontSize = UiUtils.dpToSp(activity, 18);
Expand Down Expand Up @@ -311,8 +310,7 @@ private List<TitleBarButtonController> getOrCreateButtonControllers(@Nullable Ma

private TitleBarButtonController createButtonController(Button button) {
TitleBarButtonController controller = new TitleBarButtonController(activity,
new NavigationIconResolver(activity, imageLoader),
imageLoader,
iconResolver,
new ButtonPresenter(topBar.getTitleBar(), button),
button,
buttonCreator,
Expand Down Expand Up @@ -379,7 +377,13 @@ private void mergeButtons(TopBarOptions options, TopBarButtons buttons, View chi
}
}
if (buttons.left != null) topBar.setLeftButtons(leftButtonControllers);
if (buttons.back.hasValue()) topBar.setBackButton(createButtonController(buttons.back));
if (buttons.back.hasValue()) {
if (buttons.back.visible.isFalse()) {
topBar.clearLeftButtons();
} else {
topBar.setBackButton(createButtonController(buttons.back));
}
}

if (options.rightButtonColor.hasValue()) topBar.setOverflowButtonColor(options.rightButtonColor.get());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package com.reactnativenavigation.utils;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.StrictMode;
import android.view.View;

import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
import com.reactnativenavigation.NavigationApplication;
import com.reactnativenavigation.R;

import java.io.FileNotFoundException;
import java.io.IOException;
Expand All @@ -20,6 +23,7 @@

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

public class ImageLoader {

Expand All @@ -33,6 +37,11 @@ public interface ImagesLoadingListener {

private static final String FILE_SCHEME = "file";

public Drawable getBackButtonIcon(Activity context) {
boolean isRTL = context.getWindow().getDecorView().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
return ContextCompat.getDrawable(context, isRTL ? R.drawable.ic_arrow_back_black_rtl_24dp : R.drawable.ic_arrow_back_black_24dp);
}

@Nullable
public Drawable loadIcon(Context context, @Nullable String uri) {
if (uri == null) return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
import com.reactnativenavigation.views.titlebar.TitleBarReactButtonView;

import java.util.Collections;
import java.util.List;

import androidx.annotation.NonNull;
Expand All @@ -36,7 +35,6 @@ public interface OnClickListener {
}

private final NavigationIconResolver navigationIconResolver;
private final ImageLoader imageLoader;
private ButtonPresenter optionsPresenter;
private final Button button;
private final ReactViewCreator viewCreator;
Expand All @@ -54,14 +52,12 @@ public String getButtonInstanceId() {

public TitleBarButtonController(Activity activity,
NavigationIconResolver navigationIconResolver,
ImageLoader imageLoader,
ButtonPresenter optionsPresenter,
Button button,
ReactViewCreator viewCreator,
OnClickListener onClickListener) {
super(activity, button.id, new YellowBoxDelegate(), new Options());
this.navigationIconResolver = navigationIconResolver;
this.imageLoader = imageLoader;
this.optionsPresenter = optionsPresenter;
this.button = button;
this.viewCreator = viewCreator;
Expand Down Expand Up @@ -104,8 +100,7 @@ public boolean onMenuItemClick(MenuItem item) {
}

public void applyNavigationIcon(Toolbar toolbar) {
Integer direction = getActivity().getWindow().getDecorView().getLayoutDirection();
navigationIconResolver.resolve(button, direction, icon -> {
navigationIconResolver.resolve(button, icon -> {
setIconColor(icon);
toolbar.setNavigationOnClickListener(view -> onPressListener.onPress(button.id));
toolbar.setNavigationIcon(icon);
Expand Down Expand Up @@ -134,8 +129,7 @@ public void addToMenu(Toolbar toolbar, int position) {
if (button.hasIcon()) {
loadIcon(new ImageLoadingListenerAdapter() {
@Override
public void onComplete(@NonNull List<Drawable> icons) {
Drawable icon = icons.get(0);
public void onComplete(@NonNull Drawable icon) {
TitleBarButtonController.this.icon = icon;
setIconColor(icon);
menuItem.setIcon(icon);
Expand All @@ -151,7 +145,7 @@ public void onComplete(@NonNull List<Drawable> icons) {
}

private void loadIcon(ImageLoader.ImagesLoadingListener callback) {
imageLoader.loadIcons(getActivity(), Collections.singletonList(button.icon.get()), callback);
navigationIconResolver.resolve(button, callback::onComplete);
}

private void setIconColor(Drawable icon) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
package com.reactnativenavigation.viewcontrollers.button;

import android.content.Context;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import android.util.Log;
import android.view.View;

import com.reactnativenavigation.R;
import com.reactnativenavigation.parse.params.Button;
import com.reactnativenavigation.react.Constants;
import com.reactnativenavigation.utils.Functions.Func1;
import com.reactnativenavigation.utils.ImageLoader;
import com.reactnativenavigation.utils.ImageLoadingListenerAdapter;

import androidx.annotation.NonNull;

public class NavigationIconResolver {

private Context context;
private Activity context;
private ImageLoader imageLoader;

public NavigationIconResolver(Context context, ImageLoader imageLoader) {
public NavigationIconResolver(Activity context, ImageLoader imageLoader) {
this.context = context;
this.imageLoader = imageLoader;
}

public void resolve(Button button, Integer direction, Func1<Drawable> onSuccess) {
if (button.icon.hasValue()) {
public void resolve(Button button, Func1<Drawable> onSuccess) {
if (button.hasIcon()) {
imageLoader.loadIcon(context, button.icon.get(), new ImageLoadingListenerAdapter() {
@Override
public void onComplete(@NonNull Drawable icon) {
Expand All @@ -38,8 +36,7 @@ public void onError(Throwable error) {
}
});
} else if (Constants.BACK_BUTTON_ID.equals(button.id)) {
Boolean isRTL = direction == View.LAYOUT_DIRECTION_RTL;
onSuccess.run(ContextCompat.getDrawable(context, isRTL ? R.drawable.ic_arrow_back_black_rtl_24dp : R.drawable.ic_arrow_back_black_24dp));
onSuccess.run(imageLoader.getBackButtonIcon(context));
} else {
Log.w("RNN", "Left button needs to have an icon");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.reactnativenavigation.utils.UiUtils;
import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
import com.reactnativenavigation.viewcontrollers.ViewController;
import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
import com.reactnativenavigation.viewcontrollers.stack.StackControllerBuilder;
import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
import com.reactnativenavigation.views.StackLayout;
Expand All @@ -38,7 +39,7 @@ protected TopBar createTopBar(Context context, StackLayout stackLayout) {
.setId("stack")
.setChildRegistry(new ChildControllersRegistry())
.setTopBarController(topBarController)
.setStackPresenter(new StackPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), new TopBarButtonCreatorMock(), new ImageLoader(), new RenderChecker(), new Options()))
.setStackPresenter(new StackPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), new TopBarButtonCreatorMock(), new NavigationIconResolver(activity, new ImageLoader()), new RenderChecker(), new Options()))
.setInitialOptions(new Options());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.reactnativenavigation.mocks;

import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class BackDrawable extends Drawable {
@Override
public void draw(@NonNull Canvas canvas) {

}

@Override
public void setAlpha(int alpha) {

}

@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {

}

@Override
public int getOpacity() {
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;

import com.reactnativenavigation.utils.ImageLoader;

Expand All @@ -13,6 +12,8 @@
import java.util.Collections;
import java.util.List;

import androidx.annotation.NonNull;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;

Expand All @@ -39,22 +40,23 @@ public int getOpacity() {
}
};

private static Drawable backIcon = new BackDrawable();

public static ImageLoader mock() {
ImageLoader imageLoader = Mockito.mock(ImageLoader.class);
doAnswer(
invocation -> {
doAnswer(invocation -> {
int urlCount = ((Collection) invocation.getArguments()[1]).size();
List<Drawable> drawables = Collections.nCopies(urlCount, mockDrawable);
((ImageLoader.ImagesLoadingListener) invocation.getArguments()[2]).onComplete(drawables);
return null;
}
).when(imageLoader).loadIcons(any(), any(), any());
doAnswer(
invocation -> {
doAnswer(invocation -> {
((ImageLoader.ImagesLoadingListener) invocation.getArguments()[2]).onComplete(mockDrawable);
return null;
}
).when(imageLoader).loadIcon(any(), any(), any());
doAnswer(invocation -> backIcon).when(imageLoader).getBackButtonIcon(any());
return imageLoader;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.reactnativenavigation.utils;

import android.app.Activity;
import androidx.appcompat.view.menu.ActionMenuItemView;
import androidx.appcompat.widget.Toolbar;

import com.reactnativenavigation.mocks.ImageLoaderMock;
import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
Expand All @@ -13,6 +11,9 @@
import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
import com.reactnativenavigation.views.titlebar.TitleBar;

import androidx.appcompat.view.menu.ActionMenuItemView;
import androidx.appcompat.widget.Toolbar;

public class TitleBarHelper {
public static ActionMenuItemView getRightButton(Toolbar toolbar, int index) {
return (ActionMenuItemView) ViewUtils.findChildrenByClassRecursive(toolbar, ActionMenuItemView.class).get(toolbar.getMenu().size() - index - 1);
Expand Down Expand Up @@ -45,7 +46,6 @@ public static Button iconButton(String id, String icon) {
public static TitleBarButtonController createButtonController(Activity activity, TitleBar titleBar, Button button) {
return new TitleBarButtonController(activity,
new NavigationIconResolver(activity, ImageLoaderMock.mock()),
ImageLoaderMock.mock(),
new ButtonPresenter(titleBar, button),
button,
new TopBarButtonCreatorMock(),
Expand Down
Loading

0 comments on commit 3f17dc4

Please sign in to comment.