flutter:获取对象&路由管理 (四)

简介: 本文介绍了Flutter中如何通过Context获取状态对象、使用GlobalKey获取状态对象、基本的路由管理、路由传值、命名路由、返回根路由以及点击图标跳转的方法。示例代码展示了如何在应用中实现这些功能,包括页面跳转、传递参数和返回上一页等操作。

前言

在现代移动应用开发中,Flutter 作为一个强大的 UI 工具包,提供了简洁高效的方式来构建美观的界面和流畅的用户体验。在 Flutter 中,状态管理和路由管理是构建应用时不可或缺的部分。掌握如何通过 BuildContext 和 GlobalKey 获取状态对象,以及如何有效地管理页面跳转、参数传递和命名路由,能够帮助开发者创建更加灵活和易于维护的应用程序。

获取对象

通过Context获取状态对象

import 'package:flutter/material.dart';
class GetStateObjectRoute extends StatefulWidget{
  const GetStateObjectRoute({super.key});
  @override
  State<StatefulWidget> createState() => _GetStateObjectRouteState();
}
class _GetStateObjectRouteState extends State<GetStateObjectRoute>{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "myApp",
      home: Scaffold(
        appBar: AppBar(
          title: const Text('子树中获取的context 对象'),
        ),
        body:Center (
        child:Column(
          children: [
            Builder(builder: (context){
              return   ElevatedButton(onPressed: (){
                ScaffoldState state=  context.findAncestorStateOfType<ScaffoldState>()!;
                state.openDrawer();
              }, child: const Text ('open the menu1'));
            }),
            Builder(builder: (context){
              return   ElevatedButton(onPressed: (){
                //通过 of 静态方法 来获取 ScaffoldState
                ScaffoldState state=  Scaffold.of(context);
                state.openDrawer();
              }, child: const Text ('open the menu2'));
            }),
            Builder(builder: (context){
              return   ElevatedButton(onPressed: (){
                //通过 of 静态方法 来获取 ScaffoldState
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('i am the SnackBar'))
                );
              }, child: const Text ('show the snackBar'));
            })
          ],
        )
        ),
        drawer: const Drawer(),
      ),
    );
  }
}
main(){
  runApp(const GetStateObjectRoute());
}

通过goableKey状态获取


先定义

// 定义一个globalKey   由于globalKey 需要保持全局唯一性,用静态存储
static final GlobalKey<ScaffoldState> _globalKey= GlobalKey();

设置

home: Scaffold(
        key:_globalKey, //设置key

调用

body:Center (
          child: Column(
            children: [
              Builder(builder: (context){
                return ElevatedButton(onPressed: (){
                //  通过GlobalKey 获取 State 对象
                  (_globalKey.currentState as ScaffoldState).openDrawer();
                }, child: const Text('open Draw1'),);
              })
            ],
          ),



路由管理

简单使用

ElevatedButton(child:const Text('login',),onPressed: (){
                // Navigator.of(context).pushNamed( "successful");
              Navigator.push(context, MaterialPageRoute(builder: (context){
                return Successful();
              }));
              },),

先定义好主页面

class HomePage extends StatelessWidget{
  const HomePage({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('home page'),
      ),
      body: Center(
        child: TextButton(
          onPressed: () {  
          //   导航 到 新路由
            Navigator.push(context, MaterialPageRoute(builder: (context){
              return const NewRoute();
            }));
          },
          child: const Text('open new route'),
        ),
      ),
    );
  }
}

再定义一个路由页面

class NewRoute extends StatefulWidget{
  const NewRoute({super.key});
  @override
  State<StatefulWidget> createState() =>_NewRoute();
}
class _NewRoute extends State<NewRoute> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title:const Text('this is new Route') ,
      ),
      body: const Center(
        child: Text("this is new route"),
      ),
    );
  }
}

启动

跳转 回来

body:  Center(
      child:Column(
        children: [
           Text(" i am news page"),   // 获取 newspage  定义 的 title
        FloatingActionButton(onPressed: (){
          Navigator.pop(context);  // 返回 到 上一页
        },child: Icon(Icons.arrow_back_ios),)
            ],
      )
    ),

路由传值

使用Navigator

ElevatedButton(onPressed: (){
                Navigator.pop(context,'i am the back element');
              }, child: const Text('back up')),

使用 result 得到

var result= await  Navigator.push(context, MaterialPageRoute(builder: (context){
             // text 也可以接受参数
                                  return const TipRoute(text: 'hello');
            }));
          print('router back the result $result');
import 'package:flutter/material.dart';
class RouterTest extends StatelessWidget{
  const RouterTest({super.key});
  @override
  Widget build(BuildContext context) {
    return Center(
        child: ElevatedButton(
          onPressed: () async{
            //   导航 到 新路由
          var result= await  Navigator.push(context, MaterialPageRoute(builder: (context){
              return const TipRoute(text: 'hello');
            }));
          print('router back the result $result');
          },
          child: const Text('open the tip page'),
        ),
    );
  }
}
class TipRoute extends StatelessWidget{
  const TipRoute({Key? key,required this.text});
  final String text;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title:const Text('tip') ,
      ),
      body:  Padding(
      padding: const EdgeInsets.all(18),
        child: Center(
          child: Column(
            children: [
              Text(text),
              ElevatedButton(onPressed: (){
                Navigator.pop(context,'i am the back element');
              }, child: const Text('back up')),
            ],
          ),
        ),
      ),
    );
  }
}
void main(List<String> args){
  runApp(const MaterialApp(
      home:RouterTest()));
}

or

SizedBox(
            child: ElevatedButton(
                onPressed: () {
                  Navigator.of(context)
                      .push(MaterialPageRoute(builder: (BuildContext context) {
                    return NewsPage(
                      title: "i am news title",
                    );
                  }));
                },
                child: Text("go to news ")),
          ),

在  newspage  页面  配置  一个 标题  

从 跳转页面 得到  接收

import 'package:flutter/material.dart';
class NewsPage extends StatefulWidget {
  final String title;
  const NewsPage({super.key,this.title="news"});
  ///  传参  得到
  @override
  State<NewsPage> createState() => _NewsPageState();
}
class _NewsPageState extends State<NewsPage> {
  @override
  Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text(widget.title),
    ),
    body: Center(
      child: Text(" i am news page"),   // 获取 newspage  定义 的 title
    ),
  );
  }
}

命名路由

class NewRoute extends StatelessWidget{
  const NewRoute({super.key});
  @override
  Widget build(BuildContext context) {
   return const Center(
      child: Text('New route,and the param is  ') ,
    );
  }
}
class HomePage extends StatelessWidget{
  const HomePage({super.key});
  @override
  Widget build(BuildContext context) {
    return Center(
      child: TextButton(
        onPressed: (){
          // 命名路由
          Navigator.of(context).pushNamed('new_page',arguments: ('hello,world'));
        }, child: const Text('go to the new route'),
      ),
    );
  }
}
void main(List<String>args){
  runApp(MaterialApp(
    title: 'myapp',
    initialRoute: '/',
    // 注册表 路由
    routes: {
      'new_page':(context)=>const NewRoute(),
      '/':(context)=>const HomePage(),
    },
  ));
}

Navigator.of(context).pushNamed( "successful");

SizedBox(
            child: ElevatedButton(
                onPressed: () {
                  Navigator.pushNamed(context, "/news");
                },
                child: Text("命名路由跳转到news")),
          ),
return  MaterialApp(
      debugShowCheckedModeBanner: false,
      // home: Tabs(),
      initialRoute: '/',
    routes: {
        "/":(context)=>const Tabs(),
      "/news":(context)=>const NewsPage(),
      "/search":(context)=>const SearchPage(),
      "/form":(context)=>const FormPage(),
    },
    );

返回根路由


如果 有 三次   路由 跳转    

使用  pushReplacementNamed   方法  返回 时 可以 跳过 第二个  路由

直接  返回 第一个路由

  1. pushReplacementNamed("/"):这是一个页面导航方法,它将根据提供的路由名称替换当前的页面。在这种情况下,路由名称为"/",表示根页面。通过将当前页面替换为根页面,您可以实现应用程序的重置或返回到初始状态的效果。


总结起来,这段代码的作用是在应用程序中导航到根页面,并替换当前页面。一旦执行了该导航操作,用户将看到根页面,并且无法通过后退按钮返回到之前的页面。


ElevatedButton(onPressed: (){
            //
            Navigator.of(context).pushReplacementNamed("/");
          }, child: Text("go back"))


点击图标跳转


创建 路由名字

GestureDetector(
            onTap: (){
              setState(() {
                Navigator.of(context).pushNamed("/personPage");
              });
            },
            child: Column(
              children: [
                Icon(Icons.home),
                Text("主页"),
              ],
            ),
          ),


相关文章
|
5月前
|
存储 前端开发 JavaScript
react怎么实现跨页面传参
react怎么实现跨页面传参
164 2
|
5月前
|
小程序
【微信小程序】-- 自定义组件 - 纯数据字段 & 组件的生命周期(三十六)
【微信小程序】-- 自定义组件 - 纯数据字段 & 组件的生命周期(三十六)
|
10月前
|
小程序 前端开发 JavaScript
微信小程序(二十二)子组件调用父组件方法,父组件调用子组件方法
制作了一个自定义组件,底部弹出菜单。 显示这个菜单的时候,首先,父组件需要调用子组件的方法,显示子组件。 点击子组件的菜单,需要调用父组件的方法进行逻辑处理。
266 0
|
2月前
|
前端开发 JavaScript API
|
4月前
|
Android开发
flutter useRootNavigator属性的作用
flutter useRootNavigator属性的作用
31 0
|
JavaScript 小程序
微信小程序 - 调用自定义组件内部方法
微信小程序 - 调用自定义组件内部方法
520 0
|
5月前
|
小程序 IDE TensorFlow
【社区每周】插件开发支持“静态懒加载”模式;小程序新增“占位组件”(2022年5月第三期)
【社区每周】插件开发支持“静态懒加载”模式;小程序新增“占位组件”(2022年5月第三期)
43 0
|
5月前
|
存储 API
Flutter中 useRootNavigator 属性的作用
Flutter中 useRootNavigator 属性的作用 在Flutter中,Navigator是管理应用程序页面导航的一个重要组件。Navigator管理着一个栈结构,用于存储应用程序中所有活动页面的历史记录。Flutter提供了许多Navigator相关的API,其中包括 useRootNavigator 属性。
103 0
|
前端开发 JavaScript
React中Refs的作用是什么?如何使用,父组件是函数组件ref如何获取子组件内容
React中Refs的作用是什么?如何使用,父组件是函数组件ref如何获取子组件内容
190 0