美文网首页
Flutter - 微信运动排行榜效果实现

Flutter - 微信运动排行榜效果实现

作者: 西半球_ | 来源:发表于2020-09-11 16:41 被阅读0次

    demo 地址: https://github.com/iotjin/jh_flutter_demo

    实现效果:

    • appbar滚动颜色渐变
    • 图片下拉放大

    效果图:

    wx_motion_top.gif

    代码

    import 'dart:convert';
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:jh_flutter_demo/base_appbar.dart';
    import 'package:jh_flutter_demo/jh_common/utils/jh_color_utils.dart';
    import 'package:jh_flutter_demo/project/configs/project_config.dart';
    import 'package:jhtoast/jhtoast.dart';
    
    class WxMotionTopPage extends StatefulWidget {
      @override
      _WxMotionTopPageState createState() => _WxMotionTopPageState();
    }
    
    class _WxMotionTopPageState extends State<WxMotionTopPage> {
      ScrollController _scrollController = ScrollController();
    
      double _imgNormalHeight = 300;
      double _imgExtraHeight = 0;
      double _imgChangeHeight = 0;
      double _scrollMinOffSet = 0;
      double _navH = 0;
      double _appbarOpacity = 0.0;
    
      var _dataArr = [];
    
      @override
      void initState() {
        super.initState();
        _navH = JhScreenUtils.navigationBarHeight;
        _imgChangeHeight = _imgNormalHeight + _imgExtraHeight;
        _scrollMinOffSet = _imgNormalHeight - _navH;
        _addListener();
    
        _loadData();
      }
    
      void _loadData() async {
        // 获取微信运动排行榜数据
        final jsonStr = await rootBundle.loadString('lib/res/wx_motion_top.json');
    
        Map dic = json.decode(jsonStr);
        List dataArr = dic['data'];
        dataArr.forEach((item) {
          //print('steps: ${item['steps']}');
          if (item['isOwn'] == true) {
            dataArr.remove(item);
            dataArr.insert(0, item);
          }
        });
        _dataArr = dataArr;
        setState(() {});
      }
    
      //滚动监听
      void _addListener() {
        _scrollController.addListener(() {
          double _y = _scrollController.offset;
    //      print("滑动距离: $_y");
    
          if (_y < _scrollMinOffSet) {
            _imgExtraHeight = -_y;
    //        print(_topH);
            setState(() {
              _imgChangeHeight = _imgNormalHeight + _imgExtraHeight;
            });
          } else {
            setState(() {
              _imgChangeHeight = _navH;
            });
          }
    //      //小于0 ,下拉放大
    //      if (_y < 0) {
    //      } else {}
    
          //appbar 透明度
          double appBarOpacity = _y / _navH;
          if (appBarOpacity < 0) {
            appBarOpacity = 0.0;
          } else if (appBarOpacity > 1) {
            appBarOpacity = 1.0;
          }
    
          //更新透明度
          setState(() {
            _appbarOpacity = appBarOpacity;
            // print('_appbarO: ${_appbarOpacity}');
          });
        });
      }
    
      @override
      void dispose() {
        //为了避免内存泄露,_scrollController.dispose
        _scrollController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(body: _body(context, _dataArr));
      }
    
      Widget _body(context, dataArr) {
        return Stack(children: <Widget>[
          Container(
            color: Colors.white,
            child: MediaQuery.removePadding(
              context: context,
              removeTop: true,
              child: ListView.builder(
                  controller: _scrollController,
                  physics: BouncingScrollPhysics(
                      parent: AlwaysScrollableScrollPhysics()),
                  itemCount: dataArr.length + 1,
                  itemBuilder: (BuildContext context, int index) {
                    if (index == 0) {
                      return Container(
                        width: double.infinity,
                        height: _imgNormalHeight,
                      );
                    }
                    return _cell(context, dataArr[index - 1]);
                  }),
            ),
          ),
          Positioned(
            top: 0,
            width: JhScreenUtils.width,
            height: _imgChangeHeight,
            child: Container(
              color: Colors.white,
              // child: Image.network(
              //   'http://img1.mukewang.com/5c18cf540001ac8206000338.jpg',
              //   fit: BoxFit.cover,
              // ),
              child: Image.asset(
                'assets/wechat/home/ic_top.jpg',
                fit: BoxFit.cover,
              ),
            ),
          ),
          Positioned(
            top: 0,
            left: 0,
            right: 0,
            child: backAppBar(context, '排行榜',
                backgroundColor: Colors.white.withOpacity(_appbarOpacity),
                rightImgPath: 'assets/images/ic_more_black.png',
                rightItemCallBack: () {
              _clickCell(context, '更多');
            }),
          ),
        ]);
      }
    
      //cell
      Widget _cell(context, item) {
        return InkWell(
            onTap: () => _clickCell(context, item['name']),
            child: Container(
              child: Column(
                children: [
                  SizedBox(height: 10),
                  Row(
                    children: [
                      Expanded(
                        flex: 12,
                        child: Container(
                          margin: EdgeInsets.only(left: 20),
                          child: Text(
                            item['isOwn'] ? '' : (item['id'] + 1).toString(),
                            style: TextStyle(fontSize: 16),
                          ),
                        ),
                      ),
                      Expanded(
                        flex: 75,
                        child: ListTile(
                          leading: Container(
                            height: 50,
                            width: 50,
                            decoration: BoxDecoration(
                              color: JhColorUtils.hexColor(item['color']),
                              borderRadius: BorderRadius.circular(25),
                            ),
                            child: Center(
                              child: Text(item['name'].substring(0, 1),
                                  style:
                                      TextStyle(color: Colors.white, fontSize: 20)),
                            ),
                          ),
                          title: Text(
                            item['name'],
                            style: TextStyle(fontSize: 16),
                          ),
                          trailing: Text(
                            item['steps'].toString(),
                            style: TextStyle(
                                fontSize: 28,
                                color: item['steps'] > 10000
                                    ? Colors.orange
                                    : KColor.kWeiXinTextColor),
                          ),
                        ),
                      ),
                      Expanded(
                        flex: 13,
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Text(
                              item['starNum'].toString(),
                              style: TextStyle(color: Colors.grey, fontSize: 12),
                            ),
                            SizedBox(height: 5),
                            InkWell(
                              child: Icon(
                                Icons.favorite,
                                color: item['isStar'] ? Colors.red : Colors.grey,
                              ),
                              onTap: () {
                                //点赞
                                setState(() {
                                  item['isStar'] = !item['isStar'];
                                  if (item['isStar']) {
                                    item['starNum']++;
                                  } else {
                                    item['starNum']--;
                                  }
                                });
                              },
                            )
                          ],
                        ),
                      ),
                    ],
                  ),
                  SizedBox(height: 10),
                  Container(
                      color: KColor.kLineColor, height: item['isOwn'] ? 10 : 1),
                ],
              ),
            ));
      }
    
      //点击cell
      _clickCell(context, text) {
        JhToast.showText(context, msg: '点击 ${text}');
      }
    }
    

    相关文章

      网友评论

          本文标题:Flutter - 微信运动排行榜效果实现

          本文链接:https://www.haomeiwen.com/subject/thrbektx.html