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、底部导航

  • 相关阅读:
    Longest Palindromic Substring
    PayPal MLSE job description
    Continuous Median
    Remove Duplicates From Linked List
    Valid IP Address
    Longest substring without duplication
    Largest range
    Subarray sort
    Multi String Search
    Suffix Trie Construction
  • 原文地址:https://www.cnblogs.com/zhangxiaoxu/p/14271552.html
Copyright © 2011-2022 走看看