Flutter_学习记录_导航和其他

Flutter 的导航页面跳转,是通过组件Navigator 和 组件MaterialPageRoute来实现的,Navigator提供了很多个方法,但是目前,我只记录我学习过程中接触到的方法:

  1. Navigator.push(), 跳转下一个页面
  2. Navigator.pop(), 返回上一个页面

1. 不带参数的页面跳转案例

代码如下:

dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: "导航演示",
    home: FirstScreen(),
  ));
}


class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("导航页面"),
      ),
      body: Center(
        child: ElevatedButton(
          style: ElevatedButton.styleFrom(
            backgroundColor: Colors.blueAccent,
            foregroundColor: Colors.white
          ),
          onPressed: (){
            Navigator.push(context, MaterialPageRoute(
                builder: (context) => SecondScreen()
              ));
          }, 
          child: Text("查看商品详情页"))
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("商品详情页")),
      body: Center(
        child: ElevatedButton(
          onPressed: (){
            Navigator.pop(context);
          }, 
          child: Text("点击返回")),
      ),
    );
  }
}

效果图:

2. 导航常数的传递和接收

代码如下:

dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: "导航演示",
    home: ProductList(products: List.generate(20, (i) => Product("商品$i", "这是一个商品详情页,编号为:$i")))
  ));
}

class ProductList extends StatelessWidget {
  // 定义一个参数
  final List<Product> products;
  // 接收参数
  const ProductList({super.key, required this.products});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar( title: Text("商品列表")),
      body: ListView.builder(
        itemCount: products.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(products[index].title),
            onTap: (){
              Navigator.push(context, MaterialPageRoute(
                builder: (context) => ProductDetail(product:products[index])
              ));
            },
          );
        })
    );
  }
}

// 商品详情页
class ProductDetail extends StatelessWidget {
   // 定义一个参数
  final Product product;
  const ProductDetail({super.key, required this.product});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(product.title)),
      body: Center(
        child: Text(product.description),
      ),
    );
  }
}

// 定义一个商品的对象
class Product {
  final String title; // 商品标题
  final String description; // 商品描述

  Product(this.title, this.description);
}

效果图如下:

3. 子页面给父级页面返回数据

代码如下:

dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: "导航演示",
    home: FirstPage()
  ));
}

 class FirstPage extends StatelessWidget {
  const FirstPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("子页面将数据回传给父视图")),
      body: Center(
        child: RouteButton(),
      ),
    );
  }
}

class RouteButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: (){
        _navigateDataToChildView(context);
      }, 
      child: Text("传递数据"));
  }

  _navigateDataToChildView(BuildContext context) async {
  	// 等待子视图返回时,回传的数据
    final result = await Navigator.push(
      context, 
      MaterialPageRoute(builder: (context) => ChildView())
    );
    // 屏幕底部的小弹窗
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(result)));
  }
}

// 子视图
class ChildView extends StatelessWidget {
  const ChildView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("子视图")),
      body: Center(
        child: Column(
          children: [
            ElevatedButton(
              onPressed: (){
                Navigator.pop(context, "回传:这是第一个数据回传");
              }, 
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.blueAccent,
                foregroundColor: Colors.white
              ),
              child: Text("第一个数据回传")
            ),
            ElevatedButton(
              onPressed: (){
                Navigator.pop(context, "回传:这是第二个数据回传");
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.orangeAccent,
                foregroundColor: Colors.white
              ), 
              child: Text("第二个数据回传")
            )
          ],
        ),
      ),
    );
  }
}

效果图如下:

Flutter_学习记录_数据回传

4. 设置导航栏的主题色

MaterialApp组件里面有个 theme属性,设置theme属性就可以设置导航栏的主题色,代码如下:

dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return  MaterialApp(
      debugShowCheckedModeBanner: true,
      home: Contrainer(),
      // 设置导航栏的主题色
      theme: ThemeData(
       appBarTheme: AppBarTheme(
         backgroundColor: Colors.yellow, // 设置导航栏颜色为蓝色
        ),
      ),
    );
  }
}

5. 导航栏的左右两侧添加操作按钮

AppBar组件中的leading是可以添加左边一个按钮,actions是可以添加右边的一组按钮,代码实例如下:

dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return  MaterialApp(
      debugShowCheckedModeBanner: true,
      home: Home(),
      theme: ThemeData(
       appBarTheme: AppBarTheme(
         backgroundColor: Colors.yellow, // 设置导航栏颜色为蓝色
        ),
      ),
    );
  }
}

class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // 添加左边的操作按钮
        leading: IconButton(
          onPressed: () => debugPrint("navigation button is pressed."), 
          icon: Icon(Icons.menu),
          tooltip: "Navigation",
        ),
        // 添加右边的操作按钮
        actions: [
          IconButton(
            onPressed: () => debugPrint("navigation button is pressed."), 
            icon: Icon(Icons.search),
            tooltip: "search",
          )
        ],
        title: Text("App Demo"),
        elevation: 0.0),
      body: Center(
        child: Text("添加导航栏的事件"),
      ),
    );
  }
}

效果图如下:

相关推荐
To_OC7 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
To_OC9 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
GitLqr9 小时前
玩转 WebSocket:从原理到 Flutter 实战
websocket·网络协议·flutter
小林ixn9 小时前
从 ??= 到 onKeyDown:一个 React 组件的“自我修养”
前端·javascript·react.js
世人万千丶9 小时前
参数管理_Flutter在鸿蒙平台路由参数最佳实践
学习·flutter·华为·harmonyos·鸿蒙
এ慕ོ冬℘゜9 小时前
前端实战:jQuery 多条件联合搜索(标题模糊查询 + 日历时间段筛选)
前端·javascript·jquery
随心点儿10 小时前
js postMessage 实现跨域发送消息-应用示例
javascript·ecmascript·postmessage
kyriewen12 小时前
我让AI改一个bug——它偷偷动了5个我没让它碰的地方
前端·javascript·ai编程
遇乐的果园12 小时前
前端学习笔记-vue加载渲染优化
前端·笔记·学习
遇乐的果园13 小时前
前端学习笔记-vue状态管理优化
前端·笔记·学习