How to return scene with mobile button

Asked

Viewed 1,561 times

0

The only way my app has to come back from the scene is by the button I created, when I click the back button of my phone the app closes.

Code of the button I created:

<TouchableHighlight
    underlayColor={'#66CDAA'}
    onPress={() => {
    this.props.navigator.pop();
    }}>
        <Image  source={require('../imgs/Voltar.png')}
</TouchableHighlight>

To navigate between the scenes I used the import {Navigator} from 'react-native-deprecated-custom-components'; and after importing the scenes I will navigate I used this code:

 <Navigator
          initialRoute={{id: 'CenaInicial'}}
          renderScene={(route, navigator) => {
            if(route.id === 'CenaInicial')
            {
              return(<CenaInicial navigator={navigator} />);
            }

So I declared all the scenes and in each of them I put the command this.props.navigator.push({ id: 'NomeDaCena' }); to change the scene. The problem is that only this command is not enough to return to the scene with the mobile button.

What I have to do for the back button of the phone make it show the previous scene instead of closing the application?

  • 1

    Can you put the full code? Where it comes from styles for example? What is this.props.navigator?

  • updated the question

2 answers

0

Hello !

Have you solved this problem yet ? If you are using React-navigation

You can add the following passage to your navigation component constructor:

    import { Platform, BackHandler } from 'react-native';


export class AppWithNavigationState extends Component {

      constructor(props) {
         super(props);
      }

      shouldCloseApp(nav) {
         return nav.index == 0;
      }

      // Esta função valida o SO do usuário, caso o desenvolvimento seja para ambas as plataformas.

      isAndroidApp() {
        return Platform.OS == 'android';
      }
      componentDidMount() {
        // backPress é o evento de Back() executado pelo Hardware.
        BackHandler.addEventListener('backPress', () => {
          if (this.shouldCloseApp(this.props.nav) || !this.isAndroidApp()) return false

          // Caso esteja usando o react-navigation ele vai disparar um evento de navegação (ele integra com o redux)
          this.props.dispatch({
            type: 'Navigation/BACK'
          })

          // ou logo abaixo algum código pra remover sua cena da pilha.
          ... 
              return true
            })
          }

It should be remembered that this solution only applies to Android.

I hope to help.

  • Unfortunately, I haven’t found the answer to my problem yet. I tested your answer and running gave an error: "Undefined is not an Object (evaluating 'Nav.index')", by chance you would know how to solve?

  • When I removed the shouldCloseApp(nav) {&#xA; return nav.index == 0;&#xA; } gave another error: "Undefined is not a Function (evaluating '_this2.shouldCloseApp(_this2.props.Nav)')"

  • @Murillocarvalho So the function shouldCloseApp, is a validation to check the stack of Navigation. That’s because in my code I’m using React-Navigation with Stack Navigator. In your case, you can replace the condition with the following section: if (route.id === 'CenaInicial' || !this.isAndroidApp())

  • I tried to replace but gave another error, gave "unespected token" and the problem was in the "." (point) of "route.id".

  • C. Silveira, would you know how to solve the "unespected token" problem? I still can’t solve the problem and I’m not finding any way out

  • Or @Murillocarvalho , maybe I can help you. You can post an image with the bug or something ? You want to pass me your code so I can download it and try to help you ?

Show 1 more comment

0


I may be wrong but I believe that Navigator already does it automatically. By clicking the back button of the phone it shows the previous scene navigator.pop()

What may be happening is that your navigation stack is empty. So, really the application will close.

Maybe the problem is in the method you are using to advance a scene.

I use it as follows:

import { createRouter } from '@exponent/ex-navigation';

import Cena from './screens/Cena';

const Router = createRouter(() => ({
    NomeDaCena: () => Cena})
)

navigator.push(Router.getRoute("NomeDaCena",{prop: 'Valor'}))

If you keep checking that the error is not in advancing the scene, you can try adding Listeners to the physical button of android:

https://facebook.github.io/react-native/docs/backhandler.html

For this just do, on the screens where you want to return the scene if the button is pressed:

  import { BackHandler } from 'react-native';

      {...}

      componentWillMount() {
        BackHandler.addEventListener('hardwareBackPress',() => {
         this.props.navigator.pop();
        });
      }

Edit: If you use Backhandler do not forget to remove Listener when the component is unmounted to avoid multiple calls from navigator.pop():

 componentWillUnmount() {
   BackHandler.removeEventListener('hardwareBackPress',() => {
     this.props.navigator.pop();
   });
 }
  • Backhandler is used in index.android or in scenes that will have the option to return?

  • In this exemplified code should be used in the scenes, since the components must have the prop Navigator.

  • I’m sorry to ask, it’s just that I’ve just started to learn Act-Act before long. In some of the scenes I use several 'this.props.Navigator.push', I should use the Backhandler code only once in each scene right after the 'render(){' or within each Touchablehighlight that changes the scene?

  • This code is defining a Listener. A Listener is a programmed structure that hears events that have been recorded for it. This means, that once declared, whenever the event "hardwareBackPress" is called, the code of the Handler will run. You only need to set that System once in all your code (index.android), if yours Handler always be the same. Or in the ways of componentWillMount() and componentWillUnmount() of each scene, as exemplified in the answer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.