Flutter入门项目解析

对于一个应用来讲,无非就是页面、导航、网络加载、动画等等,那么Flutter也不例外,现在从官方入门项目来分析一下Flutter的基本结构。

库的引入(使用外部包)

  • Flutter的外部包都放在这个文件下

在这里插入图片描述

	dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  english_words: ^3.1.0
  • Flutter的代码文件后缀为 .dart文件
    在这里插入图片描述

有状态的部件(Stateful widget)

  • 有完整的生命周期
  • 可以在项目中的任何地方使用
  • 创建方法
class RandomWords extends StatefulWidget {
  @override
  createState() => new RandomWordsState();
}
  • 创建最小的状态类
class RandomWordsState extends State<RandomWords> {
  @override
  Widget build(BuildContext context) {
    final wordPair = new WordPair.random();
    return new Text(wordPair.asPascalCase);
  }
}
  • 使用上面的状态类,在我看来就是一个小的视图组件
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final wordPair = new WordPair.random();  // 删除此行

    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(
          //child: new Text(wordPair.asPascalCase),
          child: new RandomWords(),
        ),
      ),
    );
  }
}

###创建可无限滚动的ListView

  • 下面这两段代码是其实类似iOS、Android原生代码。ListView其实也就相当于RecycleView和TableView且自带上拉加载。ListView自带一个builder方法,这个方法中首先设定了Row的行内边距的距离,然后实现了itemBuilder方法,Builder方法中有个自增的i,i是控制分割线,然后index控制内容。通过刚开始的index来实现滚动的时候无限刷新内容
class RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[];
  final _biggerFont = const TextStyle(fontSize: 18.0);
  
  Widget _buildSuggestions() {
    return new ListView.builder(
      padding: const EdgeInsets.all(16.0),
      // 对于每个建议的单词对都会调用一次itemBuilder,然后将单词对添加到ListTile行中
      // 在偶数行,该函数会为单词对添加一个ListTile row.
      // 在奇数行,该行书湖添加一个分割线widget,来分隔相邻的词对。
      // 注意,在小屏幕上,分割线看起来可能比较吃力。
      itemBuilder: (context, i) {
        // 在每一列之前,添加一个1像素高的分隔线widget
        if (i.isOdd) return new Divider();

        // 语法 "i ~/ 2" 表示i除以2,但返回值是整形(向下取整),比如i为:1, 2, 3, 4, 5
        // 时,结果为0, 1, 1, 2, 2, 这可以计算出ListView中减去分隔线后的实际单词对数量
        final index = i ~/ 2;
        // 如果是建议列表中最后一个单词对
        if (index >= _suggestions.length) {
          // ...接着再生成10个单词对,然后添加到建议列表
          _suggestions.addAll(generateWordPairs().take(10));
        }
        return _buildRow(_suggestions[index]);
      }
    );
  }
	Widget _buildRow(WordPair pair) {
    return new ListTile(
      title: new Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
    );
  }
}
  • 一切写好之后,调用即可
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
//    final wordPair = new WordPair.random();
    return new MaterialApp(
      title: 'Startup Name Generator',

      // 主题
      theme: new ThemeData(
        primaryColor: Colors.white,
      ),
      home: new Scaffold(
        body: new Center(
//          child: new Text('Hello World'),
        child: new RandomWords(),
        ),
      ),
    );
  }
}

添加交互方法 收藏功能

  • 创建Set集合,用来保存每一行的内容。用Set是因为Set不允许存在重复的内容
class RandomWordsState extends State<RandomWords> {
  final _saved = new Set<WordPair>();
}
  • 添加一个alreadySaved属性,来判断是否已经被点击
Widget _buildRow(WordPair pair) {
  final alreadySaved = _saved.contains(pair);
  ...
}
  • 添加示例图标
Widget _buildRow(WordPair pair) {
  final alreadySaved = _saved.contains(pair);
  return new ListTile(
    title: new Text(
      pair.asPascalCase,
      style: _biggerFont,
    ),
    trailing: new Icon(
      alreadySaved ? Icons.favorite : Icons.favorite_border,
      color: alreadySaved ? Colors.red : null,
    ),
  );
}
  • 赋予点击能力,在点击被调用的时候,处理点击逻辑
Widget _buildRow(WordPair pair) {
  final alreadySaved = _saved.contains(pair);
  return new ListTile(
    title: new Text(
      pair.asPascalCase,
      style: _biggerFont,
    ),
    trailing: new Icon(
      alreadySaved ? Icons.favorite : Icons.favorite_border,
      color: alreadySaved ? Colors.red : null,
    ),
    onTap: () {
      setState(() {
        if (alreadySaved) {
          _saved.remove(pair);
        } else {
          _saved.add(pair);
        }
      });
    },
  );
}
  • 添加导航
class RandomWordsState extends State<RandomWords> {
  ...
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Startup Name Generator'),
        actions: <Widget>[
          new IconButton(icon: new Icon(Icons.list), onPressed: _pushSaved),
        ],
      ),
      body: _buildSuggestions(),
    );
  }
  ...
}
  • 添加Push方法 Push到一个新的列表页 自带Pop方法
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();
      },
    ),
  );
}
  • 使用主题
theme: new ThemeData(
        primaryColor: Colors.white,
      ),

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值