I use react-navigation in my app.
If I navigate from screen A to Screen B, how can I got some feedback, if the transition is completed.
import { InteractionManager } from 'react-native and then
componentDidMount(){
InteractionManager.runAfterInteractions(() => {
//your code
})
}
Related
So I use this function to handle android back button :
this._page.on(Page.loadedEvent, event => {
if (application.android) {
application.android.on(application.AndroidApplication.activityBackPressedEvent, (args:AndroidActivityBackPressedEventData) => {
args.cancel = true;
this._ngZone.run(() => {
this.router.navigate(['/parameters']);
});
});
}
})
on different pages (angular components). So on page1.ts I have navigate(['/parameters]) and on page2.ts I have console.log("test"). Problem is wherever I am in the app, pressing back button always do navigate(['/parameters]), also the console.log if i'm on the right page, but it should do console.log only.
It seems to be global, any idea how to override activityBackPressedEvent ?
activityBackPressedEvent is not specific to a page, it's global to your Activity which holds all the pages. Generally, You will not add more than one event listener to this event.
You could do something like below to handle this on page level, probably in app module / main.ts
application.android.on(application.AndroidApplication.activityBackPressedEvent,
(args: application.AndroidActivityBackPressedEventData) => {
const page = frame.topmost().currentPage;
if (page.hasListeners(application.AndroidApplication.activityBackPressedEvent)) {
args.cancel = true;
page.notify({
eventName: application.AndroidApplication.activityBackPressedEvent,
object: page
});
}
});
With above code, activityBackPressedEvent willl be triggered on every page that has a listener.
Now in your page / component in which you want to customise the behaviour you do this,
// Inject Page
constructor(private page: Page) {
this.page.on(application.AndroidApplication.activityBackPressedEvent, this.onBackButtonTap, this);
}
onBackButtonTap(data: EventData) {
this._ngZone.run(() => {
this.router.navigate(['/parameters']);
});
}
I think since you added the handle back button in the event pageLoaded that's why it does not work on other page.
The code that handle back button should be placed in the app starter. I'm using NS Vue & I place this code in my main.js. I think it could be similar in NS angular.
application.android.on(application.AndroidApplication.activityBackPressedEvent, (args:AndroidActivityBackPressedEventData) => {
args.cancel = true;
this._ngZone.run(() => {
this.router.navigate(['/parameters']);
});
});
I´m having a hard time understanding what am i missing here when the user receives a push notification and then hits the button in order to see it and navigate to the proper page inside the app, so my code is this and by the way it works very well in ios:
So if the application is android, i use this code below... i receive the content and pass it to a function called handleOpenURL
if (application.android) {
application.on(application.launchEvent, (args) => {
try {
TnsOneSignal.startInit(application.android.context).setNotificationOpenedHandler(new TnsOneSignal.NotificationOpenedHandler({
// notificationOpened: function (result: com.onesignal.OSNotificationOpenResult) {
notificationOpened: function (result) {
const imovelAndroid = JSON.parse(result.stringify()).notification.payload.additionalData;
handleOpenURL(imovelAndroid);
}
})).init();
TnsOneSignal.setInFocusDisplaying(TnsOneSignal.OSInFocusDisplayOption.Notification);
TnsOneSignal.startInit(application.android.context).init();
}
catch (error) {
console.error('error', error);
}
});
}
I´m actually entering the function below, but the problem is when navigating, it simply does not work:
function handleOpenURL(argImovel) {
const precoToNumber = +argImovel['imovel'].preco;
const precoFormated = Number(precoToNumber).toLocaleString("pt-PT", { minimumFractionDigits: 0 });
const navigationOptions = {
moduleName: "detail/detail-page",
context:{ //my context here which is big so i´m not putting it.
}
};
frameModule.topmost().navigate(navigationOptions);
}
Everything works as expected in ios, it is suppose to receive the push, and when the user hits it, the app should navigate to a detail page where the content receive is showned.
What am i missing? thanks for your time, regards.
EDIT
Thanks to Manoj, i fixed the issue adding this to my handleOpenURL function:
setTimeout(() => {
frameModule.topmost().navigate(navigationOptions);
}, 2);
Make sure your Frame is ready for navigation, try logging frameModule.topmost() and see if that is a valid frame.
May be you could try a timeout of 1 or 2 secs and see whether that fixes the issue.
I have the following navigation structure in my React Native app:
StackNavigator configured with 3 routes:
Splash screen (React Component)
StackNavigator for my login flow
DrawerNavigator for my core app screens.
The DrawerNavigator has some dynamic multiple routes, but also one static route which is another StackNavigator.
Everything seems to be working as expected:
The store is being updated accordingly.
Navigation between screen works.
Go back between screen works when configured within each component, with the following command:
this.props.navigation.goBack();
My question is - is there a way for me to handle back button on Android globally? Currently when I click on the back button, nothing happens (due to the fact I'm using Redux). Should I handle the back button in each component or is there a way of doing it using Redux?
A bit late, but there is a way to handle this with redux. In your index.js file where you create your store you can make export a class and add a componentWillMount call to handle dispatching a call to your redux actions. Just remember to import the actions you need above.
const store = configureStore();
export default class Index extends Component {
componentWillMount = () => {
BackHandler.addEventListener('hardwareBackPress', () => {
const { nav: { routes } } = store.getState();
const currentRouteName = routes[routes.length-1].routeName;
if (currentRouteName === 'EditCoupleProfile') {
store.dispatch(editCoupleActions.navigateBack())
} else if ( currentRouteName === 'EditInterests' ) {
store.dispatch(interestsActions.navigateBack())
} else {
store.dispatch(popFromStack());
}
return true;
})
};
componentWillUnmount = () => {
BackHandler.removeEventListener('hardwareBackPress');
};
render() {
return (
<Provider store={store}>
<AppWithNavigation />
</Provider>
);
}
}
I'm using react native tab view https://github.com/react-native-community/react-native-tab-view to have something like a carousel. It seems to work fine, but the sliding transition is too fast for me. How can I configure it? Docs say that there's a configureTransition callback which should return the transition configuration, but doesn't say what's that configuration and how should it look like:
configureTransition - optional callback which returns a configuration for
the transition, return null to disable animation
Please, help me to find out how to configure transition speed.
Transition spec is defined in this file.
import { Animated } from 'react-native';
_configureTransition = () => {
return {
timing: Animated.spring,
tension: 300,
friction: 100,
};
}
render() {
return (
<TabViewAnimated
....
configureTransition={this._configureTransition}
/>
);
}
I am using an ionic tabs project. IONIC uses angular JS's ui-router for routing.
In a tab I want to have multiple state and I want to route between states.
for routing between states i am using $state.g();
here is my code:
app.js
.config(function($stateProvider,$urlRouterProvider){
$stateProvider
.state('footer',{
url:'/footer',
abstract:true,
templateUrl:'templates/footer.html'
})
.state('footer.home',{
url:'/home',
abstract:true,
views:{
'footer-home':{
templateUrl:'/templates/hometemplate.html',
controller:'HomeCtrl'
}
}
})
.state('footer.home.mainhome',{
url:'/mainhome',
parent:'footer.home',
views:{
'footer-home-landing':{
templateUrl:'/templates/myHome.html',
controller:'HomeCtrl'
}
}
})
.state('footer.home.about',{
url:'/about',
parent:'footer.home',
views:{
'footer-home-about':{
templateUrl:'templates/test.html',//template:'<p>asasdfa</p>',
controller:'AboutCtrl'
}
}
})
hometemplate.html: i have two ion-nav-view's inside on ion-nav-view
<ion-nav-view view-title="HomeTemplate">
<ion-nav-view name="footer-home-landing"></ion-nav-view>
<ion-nav-view name="footer-home-about"></ion-nav-view>
</ion-nav-view >
Now in myHome.html i have an image. on click of image I am using $state.go('footer.home.about');
In my test.html, i have one image on click of it want to take back to my myHome.html using $state.go('footer.home.myhome').
Here comes the problem. while going back to 'footer.home.myhome' myhome contents are not getting displayed. still the test.html contents are displaying but the click events on it are not triggering.
Strange behavior. Not understanding where I did wrong.
its almost like angular js, no need to worry about ionic.
Can somebody help me?
Not sure if this is just a mistake in your question but you should be using $state.go('footer.home.mainhome') instead of 'myhome'
The way i was trying is not correct.
found the right way of doing it here: http://codepen.io/TimothyKrell/pen/bnukj
so, instead loading two child states in an abstract state, have one state and have the other as their child state.
my code is not this way
.state('footer',{
url:'/footer',
abstract:true,
// views:{
// 'MainScreen':{
templateUrl:'templates/footer.html',
data: {
requireLogin: true
}
//}
//}
})
.state('footer.home',{
url:'/home',
// abstract:true,
views:{
'footer-home':{
templateUrl:'/templates/Home.html',
controller:'HIPACCtrl'
},
}
})
.state('footer.home.about',{
url:'/abouthipac',
//parent:'footer.home',
views:{
'footer-home#footer':{
templateUrl:'templates/test.html',//template:'<p>asasdfa</p>',
controller:'AboutCtrl'
}
}
})