zoukankan      html  css  js  c++  java
  • 用 Flutter 搭建标签+导航框架

    前言


          在 Flutter 这个分类的第一篇文章总结了下最新的 Mac 搭建 Flutter 开发环境和对声明式UI这个理解的东西,前面也有提过,准备像在 SwiftUI 分类中那样花一些功夫来写一个 Flutter 项目Demo,这样能更有利于我们的学习,后续的问题在日常开发的过程中再慢慢的总结吧。

          模式还是按照 SwiftUI 的,我们写一个标签+导航的模式,具体的Demo 效果如下所示,我们在看几个比较具体的概念性东西。

    Widget 的性质

          我自己写了这几个界面之后深切的体会到 Widget 真实Flutter 中一个很重要的概念,要是把它展开了往细了说,真的能写出一片文章出来,在下面的参考文章中第一篇就有详细的介绍这个Widget, 有需要的小伙伴可以去仔细看看这篇文章,那什么是 Widget 呢?我们先从 Flutter 的架构图说起,如下:

          我觉得这张图能很清晰的反映出 Widget 在整个 Flutter 中的位置,在 Flutter 的世界里,包括 Views、 View Controllers,、Layouts 等在内的概念都建立在 Widget 之上。Widget 是 Flutter 功能的抽象描述,也就是一切皆为 Widget(这点反应在SwiftUI 中我觉得和 View 的性质有点像)。

          我们这里就不详细的解读 Widget 了,具体的内容还是推荐下面的参考文章,因为说的已经很详细了, 它的一个大概的导图还是有必要给出来的,顺着这个结构往下去了解它比较的合理。

          等后面自己学习的比较深入的时候也可以回过头来总结梳理一下 Widget,了解了掌握了才有资格具体的去分析总结它,暂时自己使用的也不是特别的多。

         

    怎么引用别的文件


          你要经常写 Swift 几乎我们不用去考虑这个问题除了一些第三方的引用,但在 Flutter 中我么你需要考虑,就像我们刚开始使用 OC 开发iOS的时候一样,当然关键字还是我们熟悉的 import 具体的我们根据上面的文件层级关系往下看看,比如说我们在 Demo 中有建立一个和 main 平级的 TabsPage,我们引用的时候是下面这样的:

    /// 导入一个和自己平级的文件
    import 'TabsPage.dart';
    

          那在比如说,在 home 文件夹下有一个 HomePage.dart ,那我们是否还能直接像上面那样直接去引用呢?,答案是不能的,我们性需要带上的所属的文件,具体的如下:

    /// 导入四个我们自己创建的文件
    import 'home/HomePage.dart';
    import 'around/AroundPage.dart';
    import 'mine/MinePage.dart';
    import 'service/ServicePage.dart';
    

          上面这个点留意一下就可以了,怕有小伙伴和我一样刚开始学搞错它。 

    BottomNavigationBar

          这个控件的作用就和我们UIKit里面的UITabBarController 类似,和SwiftUI中的TabView一样,说说它具体的一些属性:

          我们再看看我们在项目Demo里面的具体的使用

    import 'package:flutter/material.dart';
    
    /// 导入四个我们自己创建的文件
    import 'home/HomePage.dart';
    import 'around/AroundPage.dart';
    import 'mine/MinePage.dart';
    import 'service/ServicePage.dart';
    
    class TabsPage extends StatefulWidget {
      TabsPage({Key key}) : super(key: key);
      @override
      _TabsPageState createState() => _TabsPageState();
    }
    
    class _TabsPageState extends State<TabsPage> {
    /// 当前选中的 index int currentIndex = 0; /// List listTabs = [ HomePage(), AroundPage(), ServicePage(), MinePage(), ]; @override Widget build(BuildContext context) { return Scaffold( /// body: this.listTabs[this.currentIndex], bottomNavigationBar: BottomNavigationBar( currentIndex: this.currentIndex, iconSize: 24.0, type: BottomNavigationBarType.fixed, onTap: (index) { setState(() { this.currentIndex = index; }); }, items: [ BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'), BottomNavigationBarItem(icon: Icon(Icons.category), label: '周边'), BottomNavigationBarItem(icon: Icon(Icons.send_rounded), label: '服务'), BottomNavigationBarItem(icon: Icon(Icons.settings), label: '我的'), ], /// 选中的颜色 fixedColor: Colors.blue, ), ); } }

          这里和我们iOS常见的是有点区别的,iOS在NavigationBarItem控制的一般都是导航控制器,我们在这里控制的等于直接是相应的控制器,然后每个控制器去管理自己的导航,有点安卓的味道,这样不错其实!具体的使用看上面的代码,我们注释写的也比较详细,我们就不在具体的解释了。

    AppBar

          没错,我们的导航来了,先看看它的具体的一些属性:

    AppBar({
        Key key,
        this.leading,//导航条左侧需要展示的Widget
        this.automaticallyImplyLeading = true,
        this.title,//导航条的标题
        this.actions,//导航条右侧要展示的一组widgets
        this.flexibleSpace,
        this.bottom,//导航条底部需要展示的widget
        this.elevation,
        this.shape,//导航条样式
        this.backgroundColor,//导航条背景色
        this.brightness,//设置导航条上面的状态栏的dark、light状态
        this.iconTheme,//导航条上的图标主题
        this.actionsIconTheme,//导航条上右侧widgets主题
        this.textTheme,//导航条上文字主题
        this.primary = true,//为false的时候会影响leading,actions、titile组件,导致向上偏移
        this.centerTitle,//导航条表示是否居中展示
        this.titleSpacing = NavigationToolbar.kMiddleSpacing,
        this.toolbarOpacity = 1.0,
        this.bottomOpacity = 1.0,
      })
    

          还有一个我们得了解一下 Scaffold ,Scaffold 是 Material library 中提供的一个 Widget, 它提供了默认的导航栏、标题和包含主屏幕 Widget 的body属性。 这里的关系就有点iOS中NaController 和 NaBar 的关系了。

          我们还是具体看看我们是怎么使用的:

    Widget build(BuildContext context) {
        return Scaffold(
          appBar: new AppBar(
            title: Text("周边"),
          ),
        );
    }
    

           复杂点的我们后面遇到了在总结,既然提到了导航那就得说一下界面之间的跳转了,我们看看像上面gif中的挑战效果我们是怎么做的,我们使用的是 Navigator 的 push方法了,看着是不是很眼熟,是不是觉得 Navigator 会有一个 pop方法,还真有!这个就比较舒服了。

          在我们的Demo中,我们是直接在push方法里面写了具体的页面的内容的在,这个正常肯定是另一个 Widget 的,相信应该明白的,我们看我们具体的代码:

    // 跳转方法
    void _pushSaved() {
        
        Navigator.of(context).push(
          new MaterialPageRoute(
            builder: (context) {
              final tiles = _saved.map(
                (pair) {
                  return new ListTile(
                    title: new Text(pair.asPascalCase, style: _biggerFont),
                  );
                },
              );
    
              final divided = ListTile.divideTiles(
                context: context,
                tiles: tiles,
              ).toList();
    
              return new Scaffold(
                appBar: new AppBar(
                  title: new Text('保存的单词'),
                ),
                body: new ListView(children: divided),
              );
            },
          ),
        );
    }
    

          上面的内容一个基本的标签+导航就出来了,后面我会不断的完善这个Demo中的内容,以此来好好学习一下这个Flutter !

    参考文章

          1、Flutter快速上车之Widget

          2、Flutter中文网

          3、BottomNavigationBar

          4、Flutter容器类组件之Scaffold、TabBar、底部导航

  • 相关阅读:
    go-go协程
    linux-pclint代码检测
    linux-32位-交叉编译openssl
    go-json类
    mysql-定时任务
    go-IO操作
    go-异常处理-error-panic-recover
    go-defer语句
    go-select
    go-指针
  • 原文地址:https://www.cnblogs.com/zhangxiaoxu/p/14271552.html
Copyright © 2011-2022 走看看