combobox 怎么实现对listview的类别查询_Flutter实战之独立实现官网Demo单词收藏Demo

概述

这是一次独立尝试,即独立完成实现Flutter文档第一个项目的最终效果,实现目标即首页为一个可无限滚动的单词列表,点击单词右边的小心心即可收藏或者取消收藏,可以在右上角的列表页查看收藏的单词,自己实现的效果如下:
首页:

d120b0a096f3ea003685826775ece592.png

单词收藏页:

49ec961253444147b37a946e759e8802.png

实现思路

看到这样一个功能,即可以分为两个页面,第一个页面本质就是一个列表页,每个列表分为两部分,即单词和收藏按钮,而第二个页面只需要显示单词,布局简单拆解:

3619a4d143bf70759de2fa5d15a25af8.png

接下我们就可以动手实践了,第一步添加需要用到的单词包english_words,即在pubspec.yaml 中,将 english_words(3.1.0或更高版本)添加到依赖项列表:

dependencies:            
flutter:            
  sdk: flutter            
  cupertino_icons: ^0.1.2            
  english_words: ^3.1.0

构建首页:

构建首页的appBar,同时注册第二个页面的路由和跳转按钮,以及定制一个简易棕色主题

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      // 去掉右上角的debug标识
      debugShowCheckedModeBanner: false,
      title: 'First Flutter',
      // 为第二个页面注册路由
      routes: {
        'love_page': (context) => LovePage(),
      },
      theme: ThemeData(
        primaryColor: Colors.grey,
      ),
      home: HomePage(),
    );
  }
}

// 首页
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: AppBar(
          title: Text('Words List'),
          actions: <Widget>[
            IconButton(
              // 第二个页面跳转按钮
              icon: Icon(Icons.list),
              onPressed: () {
                Navigator.pushNamed(context, 'love_page');
              },
            ),
          ],
        ),
        // 单词列表页面
        body: RandomWords());
  }
}

构建单词列表及样式制定

构建一个单词列表,并定制列表单行(Container)的样式,比如背景white-black渐变效果,单词(child)字体大小及颜色,单词和按钮的布局,比如利用Expanded实现空白部分的扩充,使得“小心心”按钮靠右,利用ListView实现一个无线懒加载的单词列表等

// 单词列表页
class RandomWords extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new ListView.builder(
      itemBuilder: (BuildContext context, int index) {
        final _wordPair = WordPair.random();
        // 单个单词行的定制,包括一个单词和一个小心心按钮
        return Container(
            padding: EdgeInsets.symmetric(horizontal: 10),
            decoration: BoxDecoration(
                // 制作一个下边框作为每行的分割线
                border: Border(
                    bottom: BorderSide(
                        color: Colors.black26, style: BorderStyle.solid)),
                // 背景颜色渐变
                gradient:
                    LinearGradient(colors: [Colors.white30, Colors.black12])),
            height: 40,
            child: Row(
              children: <Widget>[
                Expanded(
                    flex: 5,
                    child: Text('$_wordPair',
                        style: TextStyle(color: Colors.brown, fontSize: 30))),
                Expanded(flex: 2, child: LoveWords(word: _wordPair)),
              ],
            ));
      },
    );
  }
}

收藏'小心心'按钮实现

由于收藏点击小心心是个状态变化的过程,所以该小部件使用StatefulWidget 定义,同时传递一个全局变量存储收藏的单词便于传递给第二个单词收藏页面显示,该按钮部件实现点击小心心时改变小心心颜色为红色同时存储点击行的单词,或者“取消收藏”

// 收藏“小心心”按钮实现
class LoveWords extends StatefulWidget {
  LoveWords({Key key, this.word}) : super(key: key);
  // 怎么获取当列的数据
  final word;
  @override
  LoveWordsState createState() => new LoveWordsState();
}

// 全局变量存储 喜欢的单词 列表
var _loveList = <WordPair>[];

class LoveWordsState extends State<LoveWords> {
  var _colors = Colors.brown[170];
  var _icons = Icons.favorite_border;
  @override
  Widget build(BuildContext context) {
    return new IconButton(
      icon: Icon(_icons, size: 30, color: _colors),
      onPressed: () {
        setState(() {
          var word = widget.word;
          if (_colors == Colors.brown[170]) {
            _colors = Colors.red;
            _icons = Icons.favorite;
            // 使用widget.word。
            _loveList.add(word);
          } else {
            _colors = Colors.brown[170];
            _icons = Icons.favorite_border;
            _loveList.remove(word);
          }
        });
      },
    );
  }
}

第二个页面: 单词收藏页面的实现

即显示收藏的单词,这里同样适用ListView展示收藏的单词列表,但是提前计算了收藏单词的数量限制了列表的大小,从而防止列表溢出。

// 显示喜欢的单词列表 页面
class LovePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(title: Text('Favorite Words')),
      body: ListView.builder(
        // 限制列表数量
        itemCount: _loveList.length,
        itemBuilder: (BuildContext context, int index) {
            return new Container(
                padding: EdgeInsets.symmetric(horizontal: 10),
                decoration: BoxDecoration(
                    border: Border(
                        bottom: BorderSide(
                            color: Colors.black26, style: BorderStyle.solid)),
                    gradient: LinearGradient(
                        colors: [Colors.white30, Colors.black12])),
                height: 40,
                child: Row(
                  children: <Widget>[
                    Expanded(
                        flex: 5,
                        child: Text(_loveList[index].toString(),
                            style:
                                TextStyle(color: Colors.brown, fontSize: 30))),
                  ],
                ));
        },
      ),
    );
  }
}

Summary

虽然实现效果和官网大致相似,但是实现代码和思路都大相径庭,可以看出官网实现的Demo对Widgets的利用确实精湛,值得深入学习!
完整代码:https://github.com/kavener/FlutterWidgets/blob/master/lib/FirstFlutter/MyApp.dart

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值