带有返回数据的Flutter Back按钮

aks*_*ksn 12 flutter flutter-layout

我有一个带有两个按钮的界面,这些按钮会弹出并返回true或false,如下所示:

onPressed: () => Navigator.pop(context, false)
Run Code Online (Sandbox Code Playgroud)

我需要调整应用栏中的后退按钮,因此它会弹出并返回false。有没有办法做到这一点?

Apo*_*leo 45

更简单的方法是将 body 包裹在WillPopScope 中,这样它将与顶部后退按钮和底部Android 后退按钮一起使用

这是两个后退按钮都返回 false 的示例:

final return = Navigator.of(context).push(MaterialPageRoute<bool>(
    builder: (BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text("New Page"),
        ),
        body: WillPopScope(
          onWillPop: () async {
             Navigator.pop(context, false);
             return false;
          },
          child: newPageStuff(),
        ),
      );
    },
));
Run Code Online (Sandbox Code Playgroud)

在他们建议使用的其他答案中:

领先:BackButton(...)

我发现这适用于顶部的后退按钮,而不适用于 Android 按钮。

我无论如何包括一个例子:

final return = Navigator.of(context).push(MaterialPageRoute<bool>(
    builder: (BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          leading: BackButton(
            onPressed: () => Navigator.pop(context, false),
          ),
          title: Text("New Page"),
        ),
        body: newPageStuff(),
      );
    },
));
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回答,对我真的很有帮助!但我建议对您的第一个解决方案进行一些改进:作为“onWillPop”参数传递的函数可以是“async”函数,以便在块的末尾您可以“return false”。 (3认同)

azi*_*iza 15

默认值BackButton接管您的Leading属性,AppBar因此您所需要做的就是leading使用自定义后退按钮覆盖该属性,例如:

leading: IconButton(icon:Icon(Icons.chevron_left),onPressed:() => Navigator.pop(context, false),),)
Run Code Online (Sandbox Code Playgroud)

  • Android 操作系统中内置有后退按钮。iOS 允许通过向右滑动返回。脚手架的“leading”属性中的自定义按钮不会处理这些其他导航方式。 (11认同)
  • 这将捕获 AppBar 上的点击,但如果用户按下 Android 手机底部的系统后退按钮,则不会捕获。 (7认同)
  • 好答案!!这对我很有帮助。但是,我们应该使用BackButtonIcon()代替Chevron来确保大小正确。请参阅文档:https://docs.flutter.io/flutter/material/BackButton-class.html和https://docs.flutter.io/flutter/material/BackButtonIcon-class.html (3认同)

BIN*_*GAR 11

这可能对您有帮助并为您工作

第一屏

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),));
Run Code Online (Sandbox Code Playgroud)

}

第二屏

Navigator.pop(context, "Hello world");
Run Code Online (Sandbox Code Playgroud)

  • 我不认为此答案涵盖了处理后退按钮的细节。 (8认同)

Jas*_*ngh 7

实现这一目标的最简单方法是:

\n\n

在你的身体中,将 aWillPopScope作为父小部件\n并在其onWillPop : () {}调用时

\n\n
Navigator.pop(context, false);\n
Run Code Online (Sandbox Code Playgroud)\n\n

onWillPopWillPopScope当您按下 AppBar 上的后退按钮时,将自动触发

\n


Dee*_*kur 7

要弹出数据并在导航上传递数据,您需要在.then()屏幕1 上使用。以下是示例。

屏幕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
  ),
Run Code Online (Sandbox Code Playgroud)

屏幕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
        });
      }
   }
Run Code Online (Sandbox Code Playgroud)


Rém*_*let 5

虽然您可以覆盖自定义行为的后退按钮,但不要这样做。

您应该处理 null 场景,而不是使用自定义弹出窗口覆盖按钮。您不想手动覆盖图标有几个原因:

  • IOS 和 Android 上的图标发生变化。在IOS上它使用arrow_back_ios而android上使用arrow_back
  • 如果没有返回路线,该图标可能会自动消失
  • 物理后退按钮仍然会返回null

相反应该执行以下操作:

var result = await Navigator.pushNamed<bool>(context, "/");
if (result == null) {
  result = false;
}
Run Code Online (Sandbox Code Playgroud)

  • 由于用户可能按下了硬件后退按钮,如何在不调用“Navigator.pop”的情况下从页面返回数据? (3认同)