IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> flutter学习之基础组件(四) -> 正文阅读

[移动开发]flutter学习之基础组件(四)

flutter学习之基础组件(四)

本节主要记录StatefulWidget有状态组件和bottomNavigationBar组件实现主页面tab切换以及路由跳转,命名路由跳转。




一、StatefulWidget 有状态组件

在 Flutter中自定义组件其实就是一个类,这个类需要继承StatelessWidget/StatefulWidget。
StatelessWidget是无状态组件,状态不可变的widget
StatefulWidget是有状态组件,持有的状态可能在widget生命周期改变。
通俗的讲:如果我 们想改变页面中的数据的话这个时候就需要用到StatefulWidget

1.使用StatefulWidget 实现一个简单的计数器

在StatefulWidget中想更新页面状态,就必须调用setState方法去刷新页面。


/**
 * 计数器
 */
class HomeContent extends StatefulWidget {
  const HomeContent({Key? key}) : super(key: key);

  @override
  _HomeContentState createState() => _HomeContentState();
}

class _HomeContentState extends State<HomeContent> {
  int count = 0;
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(height: 200,),
        Chip(label: Text("你好 $count")),
        ElevatedButton(
          onPressed: () {
            setState(() {
              count++;
            });
          },
          child: Text("+1"),
        ),
      ],
    );
  }
}

2.使用StatefulWidget 动态添加列表

/**
 * list 动态添加数据
 */
class ListStateContent extends StatefulWidget {
  const ListStateContent({Key? key}) : super(key: key);

  @override
  _ListStateContentState createState() => _ListStateContentState();
}

class _ListStateContentState extends State<ListStateContent> {

  List list = [];
  int count = 0;
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        Column(
          children: this.list.map((value){
            return ListTile(
              title: Text(value),
              subtitle: Text("这是内容"),
              leading: Icon(Icons.ac_unit_sharp),
            );
          }).toList(),
        ),
       SizedBox(height: 20,),
        ElevatedButton(
          onPressed: () {
          setState(() {
            list.add("data $count");
            count++;
          });
        },
        child: Text("添加数据"),

        )
      ],
    );
  }
}

二、bottomNavigationBar组件

BottomNavigationBar是底部导航条,可以让我们定义底部Tab切换,bottomNavigationBar是Scaffold组件的参数。
效果:
在这里插入图片描述

1.BottomNavigationBar常见的属性

在这里插入图片描述
注:如果底部tab超过三个,必须设置type,否则会出现bug,显示问题

2.BottomNavigationBar实现可以左右切换页面的主页

先创建四个主页相关的页面
在这里插入图片描述

import 'package:flutter/cupertino.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("首页"),
    );
  }
}
class MessagePage extends StatefulWidget {
  const MessagePage({Key? key}) : super(key: key);

  @override
  _MessagePageState createState() => _MessagePageState();
}

class _MessagePageState extends State<MessagePage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("消息页面"),
    );
  }
}

class MinePage extends StatefulWidget {
  const MinePage({Key? key}) : super(key: key);

  @override
  _MinePageState createState() => _MinePageState();
}

class _MinePageState extends State<MinePage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("我的页面"),
    );
  }
}

class SettingPage extends StatefulWidget {
  const SettingPage({Key? key}) : super(key: key);

  @override
  _SettingPageState createState() => _SettingPageState();
}

class _SettingPageState extends State<SettingPage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("设置"),
    );
  }
}

在创建首页页面

class TestTen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TabState(index: 0,)
    );
  }
}

编写首页bottomNavigationBar相关逻辑

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_view_demo/demoFour/pages/page/HomePage.dart';
import 'package:flutter_view_demo/demoFour/pages/page/MessagePage.dart';
import 'package:flutter_view_demo/demoFour/pages/page/MinePage.dart';
import 'package:flutter_view_demo/demoFour/pages/page/SettingPage.dart';

class TabState extends StatefulWidget {
  final index ;
  TabState({Key? key, this.index = 0}) : super(key: key);

  @override
  _TabStateState createState() => _TabStateState(index);
}

class _TabStateState extends State<TabState> {
  int _currentIndex = 0;

	//tab对于页面集合
  List<Widget> _pageList = [
    HomePage(),
    MessagePage(),
    SettingPage(),
    MinePage()
  ];

  _TabStateState(int currentIndex){
    this._currentIndex = currentIndex;
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("BottemNativigationBar组件"),),
      body: _pageList[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
   //     backgroundColor: Colors.red[600],
        currentIndex: _currentIndex,
        onTap: (int index){
          setState(() {
            _currentIndex = index;		//更新tab切换状态
          });
        },
        fixedColor: Colors.red, //选中的颜色
        type: BottomNavigationBarType.fixed,  //配置底部可以有多个按钮,否则超出3个会有问题
        items: [
          BottomNavigationBarItem(
              icon: Icon(Icons.home),
              title: Text("首页")
          ),
          BottomNavigationBarItem(
              icon: Icon(Icons.message),
              title: Text("消息")
          ),
          BottomNavigationBarItem(
              icon: Icon(Icons.settings),
              title: Text("设置")
          ),
          BottomNavigationBarItem(
              icon: Icon(Icons.info_outline_sharp),
              title: Text("我的")
          )
        ],
      ),
    );
  }
}

三、Flutter中的路由

Flutter中的路由通俗的讲就是页面跳转。在Flutter中通过Navigator组件管理路由导航。 并提供了管理堆栈的方法。如:Navigator.push 和 Navigator.pop
Flutter 中给我们提供了两种配置路由跳转的方式:1、基本路由 2、命名路由

1.基本路由使用

基本路由使用有两种,一种是直接跳转,一种是传值跳转,参考代码


class TestEleven extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: Text("路由,跳转"),),
          body: NavigatorState()
        ),
    );
  }
}

class NavigatorState extends StatefulWidget {
  const NavigatorState({Key? key}) : super(key: key);

  @override
  _NavigatorStateState createState() => _NavigatorStateState();
}

class _NavigatorStateState extends State<NavigatorState> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          ElevatedButton(onPressed: (){
            Navigator.of(context).push(
                MaterialPageRoute(builder: (context)=>TestTen())
            );
          },
              child: Text("普通路由跳转到主页")),
          ElevatedButton(onPressed: (){
            Navigator.of(context).push(
                MaterialPageRoute(builder: (context)=>ListPage("跳转到列表页面,并且传值"))
            );
          },
              child: Text("普通路由传值")),
        ],
      ),
    );
  }
}


class ListPage extends StatelessWidget{
  late String _title;
	//获取传过来的值
  ListPage(this._title,{Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("搜索页面"),),
      body: ListView(
        children: [
          ListTile(
          //赋值
            title: Text(_title),
          ),
          ListTile(
            title: Text(_title),
          ),
          ListTile(
            title: Text(_title),
          ),
          ListTile(
            title: Text(_title),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.of(context).pop(); //自定义返回
      },
        child: Text("返回"),
      ),
    );
  }
}

2.命名路由简单使用

命名路由跳转需要在MaterialApp下配置routes属性,routes里面配置跳转别名和跳转页面

class TestEleven extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: Text("路由,跳转"),),
          body: NavigatorState()
        ),
      routes: {       //命名路由
          "/TestTen" : (context) =>TestTen(),
          "/ListPage" : (context) =>ListPage("跳转到列表页面,并且传值"),
      },
    );
  }
}

class NavigatorState extends StatefulWidget {
  const NavigatorState({Key? key}) : super(key: key);

  @override
  _NavigatorStateState createState() => _NavigatorStateState();
}

class _NavigatorStateState extends State<NavigatorState> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          ElevatedButton(onPressed: (){
            Navigator.pushNamed(context, "/ListPage");
          },
              child: Text("命名路由传值")),
        ],
      ),
    );
  }
}

3…命名路由跳转传值

参考官网文档https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments
官方介绍:

	在Navigator提供了从使用公共标识符的应用程序的任何部分定位到一个命名的路由的能力。在某些情况下,您可能还需要将参数传递给命名路由。例如,您可能希望导航到该/user路线并将有关用户的信息传递到该路线。
您可以使用方法的arguments参数 完成此任务Navigator.pushNamed()。使用ModalRoute.of()方法或在onGenerateRoute() 提供给MaterialApp或CupertinoApp 构造函数的函数中提取参数 。
这个秘籍演示了如何将参数传递给命名路由ModalRoute.of() 并onGenerateRoute()使用以下步骤读取参数:
	定义需要传递的参数。
	创建一个提取参数的小部件。
	在routes表中注册小部件。
	导航到小部件。

这块功能具体可以抽取出来,统一管理一个跳转类:
定义一个跳转类Routes

import 'package:flutter/material.dart';
import 'package:flutter_view_demo/demoFour/TestTen.dart';
import 'package:flutter_view_demo/demoFour/pages/MingMinPage.dart';
import 'package:flutter_view_demo/demoFour/pages/user/Login.dart';
import 'package:flutter_view_demo/demoFour/pages/user/RegisterFirst.dart';
import 'package:flutter_view_demo/demoFour/pages/user/RegisterSecond.dart';
import 'package:flutter_view_demo/demoFour/pages/user/RegisterThird.dart';
import 'package:flutter_view_demo/demoThree/TestSeven.dart';

//配置路由,定义Map类型的routes,Key为String类型,Value为Function类型
final Map<String,Function> routes={
    //  '/':(context)=>Tabs(),
      '/TestTen':(context)=>TestTen(),
      '/TestSeven':(context)=>TestSeven(),
      '/MingMinState':(context,{arguments})=>MingMinState(arguments:arguments),
      '/LoginPage':(context,{arguments})=>LoginPage(),
      '/RegisterFirstPage':(context,{arguments})=>RegisterFirstPage(),
      '/RegisterSecondPage':(context,{arguments})=>RegisterSecondPage(),
      '/RegisterThirdPage':(context,{arguments})=>RegisterThirdPage(),

};

//固定写法
var onGenerateRoute=(RouteSettings settings) {      
      //String? 表示name为可空类型
      final String? name = settings.name; 
      //Function? 表示pageContentBuilder为可空类型
      final Function? pageContentBuilder = routes[name];      
      if (pageContentBuilder != null) {
        if (settings.arguments != null) {
          final Route route = MaterialPageRoute(
              builder: (context) =>
                  pageContentBuilder(context, arguments: settings.arguments));
          return route;
        }else{
            final Route route = MaterialPageRoute(
              builder: (context) =>
                  pageContentBuilder(context));
            return route;
        }
      }
};

在MaterialApp中配置:
onGenerateRoute: onGenerateRoute, //配置命名路由
就实现了命名路由功能

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_view_demo/routes/Routes.dart';

class TestTwelve extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("命名路由传值"),
          ),
          body: NavigatorState()),
      onGenerateRoute: onGenerateRoute, //配置命名路由
    );
  }
}

class NavigatorState extends StatefulWidget {
  const NavigatorState({Key? key}) : super(key: key);

  @override
  _NavigatorStateState createState() => _NavigatorStateState();
}

class _NavigatorStateState extends State<NavigatorState> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, "/TestSeven");
              },
              child: Text("命名正常跳转")),
          ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, "/MingMinState",
                    arguments: {"id": 123, "name": "王"});
              },
              child: Text("命名路由传值")),
          ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, "/LoginPage");
              },
              child: Text("跳转到登录")),
          ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, "/RegisterFirstPage");
              },
              child: Text("跳转到注册")),
        ],
      ),
    );
  }
}

接收到传值,并处理

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class MingMinState extends StatefulWidget {
  var arguments;
  MingMinState({Key? key, this.arguments}) : super(key: key);

  @override
  _MingMinStateState createState() => _MingMinStateState(this.arguments);
}

class _MingMinStateState extends State<MingMinState> {
  Map arguments;
  _MingMinStateState(this.arguments);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("命名路由接受值"),),
      body: Center(
        child: Column(
          children: [
            Text(arguments["id"].toString()),
            Text(arguments["name"]),
          ],
        ),
      ),
    );
  }
}

4.Flutter中返回到上一级页面

Navigator.of(context).pop();  //返回到上一页

5.替换路由

通过pushReplacementNamed跳转的页面,相当于下一个页面复用的上一页页面,点击返回,直接就返回到了根页面

Navigator.of(context).pushReplacementNamed('/RegisterSecondPage');

6.返回到根路由

下面代码如果执行了,先跳转到指定页面,然后会把这个页面之前的页面都置为空,就剩下一个页面,点击返回,直接就退出APP

Navigator.of(context).pushAndRemoveUntil(
new MaterialPageRoute(builder: (context) => new TabState(index:1)), (route) => route == null
);

总结

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 11:48:06  更:2021-07-25 11:48:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 20:18:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码