wix / react-native-navigation Goto Github PK
View Code? Open in Web Editor NEWA complete native navigation solution for React Native
Home Page: https://wix.github.io/react-native-navigation/
License: MIT License
A complete native navigation solution for React Native
Home Page: https://wix.github.io/react-native-navigation/
License: MIT License
There are 2 major problems in software:
Seriously though, the current naming convention is based on facebook's Navigation apis, and IMHO is a mess.
It's partly based on iOS naming, highly inconsistent between the platforms, and generally confusing.
We broke the app into major abstract components:
DeviceStatusBar
- the bar at the top of the screen, where the battery indicator restsAppLayout
- the layout of the entire app. Everything rests inside it. Can be SingleScreen
or TabBased
, also can hold a SideMenu
, also holds AppStyle (default styles for all screens if not specified)
BottomTabs
- Self explanatory, exists inside the AppLayout
of type TabBased
, can be hiddenScreen
- Holds the TopBar
and the ContentView
TopBar
- One per Screen
, can be hidden, autohidden on scroll, collapsing with image (future feature). Contains TitleBar
and TopTabs
.
TitleBar
- (AKA NavigationBar in iOS and ActionBar/AppBar in Android), The actual bar where you place the title
, left button
(menu toggle, back, close), right buttons
.TopTabs
- Just under the TitleBar
, implemented as a segmented control on iOS and ViewPager tabs on Android. This is (currently) the secondary navigation, ie. You cannot push to a tab under a TopTab
.ContentView
- the thing you render in your render
functions in your registered react components.SideMenu
, self explanatory, exists as AppLayout
-level scope, along with BottomTabs
.AndroidNavigationBar
- a special component - (exist on Android only, and not on all devices) the bar at the bottom most of the screen where the back, home, and recents buttons are. Some devices (like Samsung) don't have this and have capacitive touch buttons instead. iOS doesn't have it at all.A few notes:
BottomTabs
holds a stack of Screen
, which means you can push
a Screen
to a specific tab, (remember each Screen
holds a TopBar
).TopTabs
does not hold stacks of screen, rather, switching / paging ContentViews
. This means you cannot push/pop to/from a TopTab
, only define it once. This can/may change in the future. This also means all TopTabs
in a single Screen
hold the same TopBar
. This means things like collapsing TopBar
will probably not work with TopTabs
.Modal
is just a new stack of Screens
placed above all other app components. You can have infinite modals, and (currently) can push to the top-most of them infinite times.newStack
(resetTo
in the old API) just removes a specific stack and replaces it with a new stack, holding a single Screen
.If you have any objections / issues / comments / suggestions: please do it --> HERE
Currently in V2, if you want to set buttons using the navigator, you need to call different functions for every platform - setButtons
for iOS and setButton
for Android.
I understand that this decision was made since Android can only have one button on the left side. However, this need to be consistent; we don’t want to make different calls when we have the same code handling both platform.
I am really not able to use react-native-navigation because when I click on the different icons at the bottom I can't fire an event or events. Really need this ability. ETA on this?
Navigation.showModal({ screen: 'example.someScreen', title: 'A Screen', navigatorStyle: {}, navigatorButtons: { leftButtons: [{ title: 'Cancel', id: 'navBarCancel' }] } });
When I set leftButtons the application crashes immediately.
There are 3 "scopes" of passProps that I can think of:
The first one is handled correctly, the second one should be the same (the current issue with it is that we don't assign screenInstanceID
to each screen under the view-pager / segmented control).
The last one was there from version 1.0.0, but it was weird. It was passed down to screens but NOT consistently, only to those screens that were defined in the same startXApp call, not to other modals / pushes.
The correct way IMO to handling it is to save the global scopes props in some globalPassProps
registry in JS and send it on each push / modal. This should guarantee consistent behavior.
Hi,
I own some screens with Image as a full background, i have flickering moment when the navigator push another screen. I'm new with react-native (6 days), i don't recognize this issue is related to this library or react-native instead.
I realize the Image component needed some of time to load my image raw. Any advice for me? i have idea for giving the Image a fade-in animation, after they loaded. Have a better solution?
Thanks
Do we have to be coupled to the Application and Activity objects?
Can we test it out separately?
Could you please add a callback event when back to main screen? thank you.
This issue was originally opened in react-native-controllers
Have I missed something, or is the iOS tint effect overriding the value entered for "tabBarBackgroundColor"?
Trying to set the background to absolute white, but always rendering grey.
NavBar shows back.
The same for Tabs.
Is anyone using Mobx instead of Redux? If yes, would it be possible to share some boilerplate?
This issue was originally opened in react-native-controllers
react-native-controllers v2.0.2
In one of my components, I have the following code
_stateChange (val) {
if (val === 'inactive') {
Modal.showController('myapp.Controller.Locked', 'slide-up');
}
}
componentDidMount () {
AppState.addEventListener('change', this._stateChange);
}
Everytime the AppSate is inactive
, the modal gets shown even if the myapp.Controller.Locked
is already showing on screen.
Maybe the Controllers
could keep track of the shown component and not show it again?
// var _currentModal;
showController: function(appKey, animationType = 'slide-up', passProps = {}) {
var controller = _controllerRegistry[appKey];
if (controller === undefined) return;
if (_currentModal === appKey) return;
_currentModal = appKey;
var layout = controller.render();
_validateDrawerProps(layout);
RCCManager.showController(layout, animationType, passProps);
}
The animation caused by the FLAG_ACTIVITY_CLEAR_TASK in the startApp call cannot be removed or edited. The option 'animationType' isn't handled on Android I guess.
Is there a particular reason to do a clear task here?
Do you think it would be possible to remove the animation with a call like overridePendingTransition?
Hi,
I just saw that you were currently working on 2.0 of RCC/RNN. I'd love for WillFocus, DidFocus notifications to be included within this.
In my case I need to perform actions when a user moves to a specific tab.
I've hacked this into the current version by sending the navigatorEventID to the RCCNavigationController and sending an app event from the viewWillAppear of RCCViewController in the same way the back buttons are handled.
onNavigatorEvent (event) { if (event.type === 'DidFocus') { this.doSomething() } }
Thanks!
Luke
As the title implies,
Place your suggestions for the new API here. If you see your idea already, upvote it (with +1) rather than duplicate.
hi team
in IOS Drawer is working fine but same functionality not working in android.
getting error undefined is not an object(evaluating 'this.props.navigator.showModal')
can some one please help how to resolve this issue
I want to use only Icons and not the labels at the TabBar, and possibly reduce the height of the TabBar.
It seems that this is a more modern to design a TabBar, because Facebook and Airbnb are already designing like this.
For react-native-controllers it has been discussed here, and some solutions are already developed:
wix-incubator/react-native-controllers#60
wix-incubator/react-native-controllers#62
wix-incubator/react-native-controllers#75
Rather, ask for a factory method. Further research required.
Tab vs Single page App. I'm considering an app that's both single page (onboard login screen) and tab base. I can't figure out how to structure this. It seems that I ha e to choose one or the other. It doesn't appear that o could hide the tabbar
In IOS when i push a new screen i see a white background on the rootview before the first react native render, since i have a dark styled app it's quite annoying.
Changing the color on rootview in AppDelegate.m to black,
or setting a screenBackgroundColor doesn't seem to to anything
This is the snippet from AppDeletage.m
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.backgroundColor = [UIColor blackColor];
This is the snipper from the screenComponent
class EventScreen extends Component { static navigatorStyle = { screenBackgroundColor: SituaColors.darkBg }; ....
Hello, is there any info about Android support progress?
Excited to discover this library, I've been trying out different navigation solutions and this seems like the one for me. I'm just wondering where you guys are at with the Android version. Is there an experimental branch you are working on. Any ideas of approach etc? Open to community involvement / PR's?
We have some hacky things we did that can be removed (must be removed actually, as they could cause issues).
Currently passing params to all Navigation commands is a complete mess. We need some consistency and the best I can think of is to parse the input of all commands in a centralised place.
Furthermore, most stuff should not be passed as parameters at all, but defined in the Screen itself. Further research is needed.
The issue here is that we don't assign screenInstanceID
to each screen under the topTabs.
As @DanielZlotin mentioned in issue https://github.com/wix/react-native-navigation/issues/74
Lifecycle events are not implemented yet but it's a critical feature that is being looked into. Could I know the timeline for this? One of the challenges I have is when architecting the Android app knowing there will be a lot of invisible react components. (And duplicates if navigated through push.) If I am not being careful with the lifecycle events I could potentially end up with bad data and other side effects. Thanks.
i call navigator.push() to push a screen, then i press back button.
if i want to get the current screen, i thick there are two ways:
push
and pop
i think the first way is better, but now, how can i do it ?
Is there a way to change the tabbar style after the app being initialized?
On SideMenu.js (Folder example) I tried change deepLink to push, but it don't working?
I have many categories on SideMenu and want when Press will push a new screen. How do create?
Thank you!
onReplaceTab2Press() {
this.props.navigator.toggleDrawer({
to: 'closed',
side: 'left',
animated: true
});
this.props.navigator.push({
title: "More",
screen: "example.PushedScreen"
});
}
is there anyway to know when a tab has become the active tab, or a way to set a callback on tab presses/changes?
In < 2.0, I was using Navigation.registerScreen
because registerComponent
is not flexible enough for me. I see that it's no longer exposed in 2.0. Can we re-expose it?
My use-case is that I'm adding both a redux store and a translation object to the React context. In case you're curious, it looks like this:
function registerWrappedComponent(screenID, generator) {
const generatorWrapper = () => {
const InternalComponent = generator();
return class extends Screen {
static navigatorStyle = InternalComponent.navigatorStyle || {};
static navigatorButtons = InternalComponent.navigatorButtons || {};
render() {
return (
<SuperProvider store={store} i18n={i18n}>
<InternalComponent navigator={this.navigator} {...this.props} />
</SuperProvider>
);
}
};
};
Navigation.registerScreen(screenID, generatorWrapper);
return generatorWrapper;
}
So we thought that it will be a good idea to share with you our plans for Version 2.0.0.
The main purpose of this issue is to create a discussion about the version scope and overall architecture.
We'll start to use Version 2.0.0 milestone to collect all PRs and issues that will be a part of the version.
This issue was originally opened in react-native-controllers.
I can't pass callback as prop to Lightbox. Is possible to perform this in some way?
My react-native version is 0.30.0, so I can't use 2.0?
if yes, how long to wait for it?
First I want to say thanks for making this library. It's working awesome on iOS!!
I'm struggling to make it work for Android though. It seems like the readme for Android breaks down half way and assumes knowledge of the Android ecosystem.
I'm also happy to PR fixes to the readme once I can figure out what's missing.
React Native 0.30
React 15.2.0
react-native-navigation 2.0.0-experimental.71
Firstly the readme says to run npm install react-native-navigation --save
but that installs version 1.X. This works for iOS but fails on Android with a missing Splash module.
An hour later I figured out that I needed the 2.0 beta and installed that. Steps 1 and 2 and great and didn't have any issues with that.
Step 3 assumes you know where to locate MainActivity
. Then after extending the class I hit a missing symbol error and guessed at importing the missing file (and also later confirmed by looking at the redux example).
Step 4 completely loses me but i've figured out how to at least make the compiler work... though the app launches with "Foo stopped running" so I must be doing something wrong here.
My fresh app had a MainApplication.java
file which I commented out and added an App.java
file like your examples. I added in the custom class (with name of App instead of MyApplication) and changed the xml file. The instructions for changing the XML is not enough for a non Android dev. I guessed by looking at the example.
Ultimately I still can't get the app to work on an upgraded RN 0.30 install (and used react-native upgrade).
Here are my changed Android files:
added android:name=".App"
to config
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.badger">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".App"
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
package com.badger;
import com.reactnativenavigation.controllers.SplashActivity;
public class MainActivity extends SplashActivity {
}
// ..../com/badger/App.java
package com.badger;
import android.support.annotation.NonNull;
import com.facebook.react.ReactPackage;
import com.reactnativenavigation.NavigationApplication;
import java.util.Collections;
import java.util.List;
public class App extends NavigationApplication {
@Override
public boolean isDebug() {
return BuildConfig.DEBUG;
}
@NonNull
@Override
public List<ReactPackage> createAdditionalReactPackages() {
return Collections.emptyList();
}
}
// ..../com/badger/MainApplication.java
/*
package com.badger;
import android.app.Application;
import android.util.Log;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
}
*/
With the logger running I get this once starting up:
08-21 16:28:57.672 2577 2577 E AndroidRuntime: FATAL EXCEPTION: main
08-21 16:28:57.672 2577 2577 E AndroidRuntime: Process: com.badger, PID: 2577
08-21 16:28:57.672 2577 2577 E AndroidRuntime: java.lang.RuntimeException: Unable to instantiate application com.badger.App: java.lang.ClassNotFoundException: Didn't find class "com.badger.App" on path: DexPathList[[zip file "/data/app/com.badger-2/base.apk"],nativeLibraryDirectories=[/data/app/com.badger-2/lib/x86, /data/app/com.badger-2/base.apk!/lib/x86, /vendor/lib, /system/lib]]
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at android.app.LoadedApk.makeApplication(LoadedApk.java:578)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4680)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at android.app.ActivityThread.-wrap1(ActivityThread.java)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "com.badger.App" on path: DexPathList[[zip file "/data/app/com.badger-2/base.apk"],nativeLibraryDirectories=[/data/app/com.badger-2/lib/x86, /data/app/com.badger-2/base.apk!/lib/x86, /vendor/lib, /system/lib]]
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at android.app.Instrumentation.newApplication(Instrumentation.java:981)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at android.app.LoadedApk.makeApplication(LoadedApk.java:573)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: ... 9 more
08-21 16:28:57.672 2577 2577 E AndroidRuntime: Suppressed: java.lang.ClassNotFoundException: com.badger.App
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at java.lang.Class.classForName(Native Method)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
08-21 16:28:57.672 2577 2577 E AndroidRuntime: ... 12 more
08-21 16:28:57.672 2577 2577 E AndroidRuntime: Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
Very confused... any help would be appreciated!!
This issue was originally opened in react-native-controllers
I see there is intention in the code to animate the alpha for the lightbox so that it fades in. However on calling the lightbox, if I have e.g.
style: {
backgroundBlur: "none",
backgroundColor: "#888888DD"
}
then the background instantly turns grey with transparency, and on dismiss it fades back nicely.
It would be great to have the background fade in also.
First, I'm a newbie to react-native and I know very little about native IOS and Android. I've bee searching for an approach to handle navigation and routing for reach-native apps. I tried react-native-router-flux and I was satisfied. So far, I like my experience with react-native-navigation. For the most part, it's easy to reason about. I started with react-native-controller but a few days ago, my demo project broke giving me react-native, react, and react-native-controller package conflicts. Nevertheless, its easy to find my way around this package.
I have a few questions,
jondanao/TheSidebarController: https://github.com/jondanao/TheSidebarController
romaonthego/RESideMenu: https://github.com/romaonthego/RESideMenu/
I ask because, similar to this package, these implementations seem ( correct me if I'm wrong) based on native view controllers.
More of a question rather than an issue, I can see you are able to set a number of static properties on a scene component e.g. static navigatorStyle = {};
- is it possible to do the same with title and backbutton enabled ? A lot of my routes have multiple entry points and would like to reuse as much config as possible.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.