前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >能动手就别吵吵!

能动手就别吵吵!

作者头像
吴延宝
发布2018-09-10 15:21:37
6320
发布2018-09-10 15:21:37
举报

Flutter能干什么?

系列:《Flutter从入门到放弃》 开发环境:Mac os + Android Studio 注意:读完本篇文章你可能会对其中的代码部分困惑,为什么要这么写? 没关系,我们会在下一节详细剖析。本节会对您思考如何使用Flutter重构您现有的项目带来一点启示。

背景

自从上回跑通了Hello World后,鲍勃对Flutter的信心大增啊。心里琢磨着能不能用Flutter实现公司现在正在做的APP的效果呢!说做就做,马上拿起电话打给弗拉德老师,刚好弗拉德老师晚上也有空,两人就约在街角的咖啡店打发时间了。

公司项目开篇

街角的咖啡店

鲍勃:“弗老师,我想尝试用Flutter实现我们公司APP的效果”

弗拉德:“嗯,给我看下要实现什么样的效果?”

鲍勃:“嗯,很简单。就是下面这样的:”

弗拉德:“UI挺简单的,我们一步步来吧。先从底部的导航栏开始做吧”

弗拉德:“你准备怎么做呢,现在有想法吗?”

鲍勃:“首先,我肯定要定义顶部每一个Tab的类TabItem.dart

1class TabItem {
2    TabItem({this.tabName, this.tabId});
3
4    String tabName;//顶部Tab的名称
5    int tabId;//顶部Tab的ID,因为需要根据不同分类ID去获取不同的内容的
6}

弗拉德:“嗯!不错”

鲍勃:“接下来,我是需要一个能在底部切换Tab的这种控件。弗老师,Flutter有这种widget吗?”

弗拉德:”嗯,你的思路很正确。确实有这样的Widget“

弗拉德:”我们需要用到MaterialAppBottomNavigationBar

弗拉德:”我们先建5个显示tab内容的布局吧:comu.dart,fit.dart,sports.dart,discovery.dart,mine.dart“ 以fit.dart为例,其它类似:

 1// 目前我们只做底部导航栏,先不考虑上面这些模块之间内容的区别,可以用同一个代替
 2import 'package:flutter/material.dart';
 3
 4class Fit extends StatefulWidget {
 5  @override
 6  FitState createState() => new FitState();
 7}
 8
 9class FitState extends State<Fit> {
10  @override
11  Widget build(BuildContext context) {
12    return new MaterialApp(
13      home: new Scaffold(
14        appBar: new AppBar(
15          title: new Text("健身"),
16        ),
17        body: new Center(
18          child: new Text('Hello fit'),
19        ),
20      ),
21    );
22  }
23}

弗拉德:“我们先把需要用到的资源放到我们的工程中,如下图所示:”

弗拉德:“然后我们看下入口main.dart,我们需要创建一个widget作为最外层的框架”

  1// 首页
  2class HomePage extends StatefulWidget {
  3    @override
  4  State<StatefulWidget> createState() {
  5    return new HomePageState();
  6  }
  7}
  8
  9class HomePageState extends State<HomePage> {
 10
 11  int _selectedIndex = 0;// 用来表示当前选择的索引,默认选择首项
 12  var images;// 存储图标
 13  // 底部导航栏的文字
 14  List<TabItem> tabs=[
 15    TabItem(
 16      tabName:'社群',
 17      tabId:0,
 18    ),
 19    TabItem(
 20      tabName:'健身',
 21      tabId:1,
 22    ),
 23    TabItem(
 24      tabName:'运动',
 25      tabId:2,
 26    ),
 27    TabItem(
 28      tabName:'发现',
 29      tabId:3,
 30    ),
 31    TabItem(
 32      tabName:'我',
 33      tabId:4,
 34    ),
 35  ];
 36
 37  var _bodyList = [
 38    new Comu(),
 39    new Fit(),
 40    new Sport(),
 41    new Discovery(),
 42    new Mine(),
 43  ];
 44  // 初始化底部展示图标的列表
 45  void init() {
 46    images = [
 47      [getImage('images/tab_association_grey.png'), getImage('images/tab_association_yellow.png')],
 48      [getImage('images/tab_training_grey.png'),getImage('images/tab_training_yellow.png')],
 49      [getImage('images/tab_sport_grey.png'), getImage('images/tab_sport_yellow.png')],
 50      [getImage('images/tab_discovery_grey.png'), getImage('images/tab_discovery_yellow.png')],
 51      [getImage('images/tab_me_grey.png'), getImage('images/tab_me_yellow.png')],
 52    ];
 53  }
 54
 55
 56  // 通过资源路径获取对应的Image
 57  Image getImage(path) {
 58    return new Image.asset(path, width:24.0, height: 24.0);
 59  }
 60
 61  // 这里是在每一次切换底部Tab时动态的去更新是否展示选中的图标
 62  Image getTabImage(int index) {
 63    if(index == _selectedIndex) {
 64      return images[index][1];
 65    } else {
 66      return images[index][0];
 67    }
 68  }
 69
 70  // 这里是设置底部文字的样式
 71  Text getTabText(int index) {
 72    return new Text(tabs[index].tabName,
 73      style: new TextStyle(fontSize: 11.0, color: Color(0xff333333)),);
 74  }
 75
 76    @override
 77  Widget build(BuildContext context) {
 78      init(); 
 79      return new MaterialApp(
 80        title: 'Welcome to Flutter',
 81        home: new Scaffold(
 82          body: _bodyList[_selectedIndex],
 83          bottomNavigationBar: new BottomNavigationBar(
 84            items: <BottomNavigationBarItem> [
 85              new BottomNavigationBarItem(icon: getTabImage(0), title: getTabText(0)),
 86              new BottomNavigationBarItem(icon: getTabImage(1), title: getTabText(1)),
 87              new BottomNavigationBarItem(icon: getTabImage(2), title: getTabText(2)),
 88              new BottomNavigationBarItem(icon: getTabImage(3), title: getTabText(3)),
 89              new BottomNavigationBarItem(icon: getTabImage(4), title: getTabText(4))
 90            ],
 91            type: BottomNavigationBarType.fixed,
 92            currentIndex: _selectedIndex,
 93            iconSize: 24.0,
 94            onTap: (index){
 95              setState((){
 96                _selectedIndex = index;
 97              });
 98            },),
 99        ),
100      );
101  }

鲍勃:“StatefulWidget是啥啊?”

弗拉德:“你可以先简单理解为这种类型的widget可以通过状态的变化来更新你的UI,后面理论阶段会仔细讲的。”

鲍勃:“好吧”

弗拉德:“接下来我们将上面的widget设置为整个应用的根widget”

 1// 入口
 2void main() => runApp(new MyApp());
 3
 4class MyApp extends StatelessWidget {
 5
 6  @override
 7  Widget build(BuildContext context) {
 8    return new MaterialApp(
 9      home: new HomePage(),
10    );
11  }
12}

弗拉德:“接下来我们跑一下,看效果吧”

鲍勃:“效果出来了,蛮不错的,调调颜色就可以了”

弗拉德:“今天就到这吧,下次有机会再聊了。拜拜!”

鲍勃:“好的,弗老师。拜拜!”

小结

由于5分钟的时间限制,我们下期详细剖析本节所涉及的以下知识:

  • 1. Flutter里面是如何加载图片资源的(网络、文件、asset等)?
  • 2. StatefulWidget与StatelessWidget各自在什么时机使用?
  • 3. 为什么总使用Scaffold,它到底是什么?
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 南京Android部落 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Flutter能干什么?
    • 背景
      • 公司项目开篇
        • 小结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档