web-dev-qa-db-fra.com

Bouton Flutter Back avec données de retour

J'ai une interface avec deux boutons qui apparaissent et retournent vrai ou faux, comme ceci:

onPressed: () => Navigator.pop(context, false)

J'ai besoin d'adapter le bouton de retour dans la barre d'applications, donc il apparaît et renvoie également faux. Existe-t-il un moyen d'y parvenir?

11
aksn

Cela peut vous aider et fonctionner pour vous

1er écran

void goToSecondScreen()async {
 var result = await Navigator.Push(_context, new MaterialPageRoute(
 builder: (BuildContext context) => new SecondScreen(context),
 fullscreenDialog: true,)
);

Scaffold.of(_context).showSnackBar(SnackBar(content: Text("$result"),duration: Duration(seconds: 3),));

}

2ème écran

Navigator.pop(context, "Hello world");
11
BINAY THAPA MAGAR

La valeur par défaut BackButton reprend la propriété principale de votre AppBar, il vous suffit donc de remplacer la propriété leading par votre bouton de retour personnalisé, par exemple:

leading: IconButton(icon:Icon(Icons.chevron_left),onPressed:() => Navigator.pop(context, false),),)
12
aziza

Pour faire apparaître les données et retransmettre les données de navigation, vous devez utiliser .then() à partir de l'écran 1. Voici l'exemple.

Écran 2:

class DetailsClassWhichYouWantToPop {
  final String date;
  final String amount;
  DetailsClassWhichYouWantToPop(this.date, this.amount);
}

void getDataAndPop() {
      DetailsClassWhichYouWantToPop detailsClass = new DetailsClassWhichYouWantToPop(dateController.text, amountController.text);
      Navigator.pop(context, detailsClass); //pop happens here
  }

new RaisedButton(
    child: new Text("Edit"),
    color:  UIData.col_button_orange,
    textColor: Colors.white,
    onPressed: getDataAndPop, //calling pop here
  ),

Écran 1:

    class Screen1 extends StatefulWidget {
          //var objectFromEditBill;
          DetailsClassWhichYouWantToPop detailsClass;

          MyBills({Key key, this.detailsClass}) : super(key: key);

          @override
          Screen1State createState() => new Screen1State();
        }

        class Screen1State extends State<Screen1> with TickerProviderStateMixin {


        void getDataFromEdit(DetailsClassWhichYouWantToPop detailClass) {
        print("natureOfExpense Value:::::: " + detailClass.date);
        print("receiptNumber value::::::: " + detailClass.amount);
      }

      void getDataFromEdit(DetailsClassWhichYouWantToPop detailClass) {
        print("natureOfExpense Value:::::: " + detailClass.natureOfExpense);
        print("receiptNumber value::::::: " + detailClass.receiptNumber);
      }

      void pushFilePath(File file) async {
        await Navigator.Push(
          context,
          MaterialPageRoute(
            builder: (context) => Screen2(fileObj: file),
          ),
        ).then((val){
          getDataFromScreen2(val); //you get details from screen2 here
        });
      }
   }
7
Deepak Thakur

Bien que vous puissiez remplacer le bouton de retour pour les comportements personnalisés, ne le faites pas.

Au lieu de remplacer le bouton par un pop personnalisé, vous devez gérer le scénario nul. Il y a plusieurs raisons pour lesquelles vous ne voulez pas remplacer manuellement l'icône:

  • L'icône change sur IOS et Android. Sur IOS il utilise arrow_back_ios while Android utilise arrow_back
  • L'icône peut disparaître automatiquement s'il n'y a pas d'itinéraire pour revenir en arrière
  • Le bouton de retour physique renverra toujours null.

Au lieu de cela, procédez comme suit:

var result = await Navigator.pushNamed<bool>(context, "/");
if (result == null) {
  result = false;
}
2
Rémi Rousselet

La façon la plus simple d'y parvenir est de:

Dans votre corps, prenez un WillPopScope comme widget parent Et sur son onPop: () {} appel

Navigator.pop(context, false);

onPop de WillPopScope sera déclenché automatiquement lorsque vous appuierez sur le bouton de retour de votre barre d'applications

1
Jaswant Singh

Vous pouvez passer des données/arguments d'un écran à l'autre,

considérez cet exemple:

screen1.Dart:

import 'package:flutter/material.Dart';
import 'screen2.Dart';

class Screen1 extends StatelessWidget {
  Screen1(this.indx);

  final int indx;

  @override
  Widget build(BuildContext context) {
    return new S1(indx: indx,);
  }
}

class S1 extends StatefulWidget {
  S1({Key key, this.indx}) : super(key: key);

  final int indx;

  @override
  S1State createState() => new S1State(indx);
}

class S1State extends State<VD> {

    int indx = 5;

  @override
  Widget build(BuildContext context) {
   return new Scaffold(
      appBar: new AppBar(
        leading: new IconButton(icon: const Icon(Icons.iconName), onPressed: () {
          Navigator.pushReplacement(context, new MaterialPageRoute(
            builder: (BuildContext context) => new Screen2(indx),
         ));
        }),
    ),
  );
 }
}

Écran 2:

import 'package:flutter/material.Dart';
import 'screen2.Dart';

class Screen2 extends StatelessWidget {
 Screen2(this.indx);

 final int indx;

 @override
 Widget build(BuildContext context) {
       return new S2(indx: indx,);
    }
 }

 class S2 extends StatefulWidget {
  S2({Key key, this.indx}) : super(key: key);

  final int indx;

  @override
  S2State createState() => new S2State(indx);
  }

 class S2State extends State<VD> {

 int indx = 1;

  @override
      Widget build(BuildContext context) {
       return new Scaffold(
          appBar: new AppBar(
            leading: new IconButton(icon: const Icon(Icons.Icons.arrow_back), onPressed: () {
              Navigator.pushReplacement(context, new MaterialPageRoute(
                builder: (BuildContext context) => new Screen1(indx),
             ));
            }),
        ),
      );
     }
    }

Pour passer des données entre les écrans, passez l'argument/les données au constructeur Screens dans Navigator.pushReplacement(). Vous pouvez passer autant d'arguments que vous le souhaitez.

Cette ligne

Navigator.pushReplacement(context, new MaterialPageRoute(
                    builder: (BuildContext context) => new Screen1(indx),
                 ));

ira à Screen1 et appellera initState et construira la méthode de Screen1 afin que vous puissiez obtenir des valeurs mises à jour.

0
ArgaPK

Utilisez le code ci-dessous pour obtenir le résultat de votre activité.

Future _startActivity() async {

Map results = await Navigator.of(context).Push(new MaterialPageRoute(builder: (BuildContext context){
  return new StartActivityForResult();
}));

if (results != null && results.containsKey('item')) {
  setState(() {
    stringFromActivity = results['item'];
    print(stringFromActivity);
  });
}
}

Code source complet

import 'package:flutter/material.Dart';
import 'activity_for_result.Dart';
import 'Dart:async';
void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
 return new MaterialApp(
   title: 'Flutter Demo',
   theme: new ThemeData(
    primarySwatch: Colors.blue,
  ),
     home: new MyHomePage(title: 'Start Activity For Result'),
  );
 }
}

class MyHomePage extends StatefulWidget {
 MyHomePage({Key key, this.title}) : super(key: key);
 final String title;

 @override
 _MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
 String stringFromActivity = 'Start Activity To Change Me \n????????????';
 @override
 Widget build(BuildContext context) {
 return new Scaffold(
  appBar: new AppBar(
    title: new Text(widget.title),
  ),
  body: new Center(
    child: new Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        new Text(
          stringFromActivity, style: new TextStyle(fontSize: 20.0), textAlign: TextAlign.center,
        ),
        new Container(height: 20.0,),
        new RaisedButton(child: new Text('Start Activity'),
          onPressed: () => _startActivity(),)
      ],
    ),
  ),
);
}

Future _startActivity() async {

Map results = await Navigator.of(context).Push(new MaterialPageRoute(builder: (BuildContext context){
  return new StartActivityForResult();
}));

if (results != null && results.containsKey('item')) {
  setState(() {
    stringFromActivity = results['item'];
    print(stringFromActivity);
  });
 }
 }
}

import 'package:flutter/material.Dart';

class StartActivityForResult extends StatelessWidget{

 List<String>list = ['????????????','????????????','????????????','????????????','????????????','????????????','????','????','????',];

 @override
 Widget build(BuildContext context) {
// TODO: implement build

  return new Scaffold(
    appBar: new AppBar(
    title: new Text('Selecte Smily'),
  ),
  body: new ListView.builder(itemBuilder: (context, i){
    return new ListTile(title: new Text(list[i]),
      onTap: (){
        Navigator.of(context).pop({'item': list[i]});
      },
    );
  }, itemCount: list.length,),
  );
 }
}

obtenir un exemple complet de fonctionnement de cela à partir de ici

0
Zulfiqar

Tout d'abord, supprimez le bouton de retour automatiquement ajouté (voir cette réponse )

Ensuite, créez votre propre bouton de retour. comme ça:

IconButton(
    onPressed: () => Navigator.pop(context, false),
    icon: Icon(Icons.arrow_back),
    )
0
Yamin