美文网首页
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