Flutter 日记App-日记本列表页

前言

日记列表页功能:

  1. 列表信息展示
  2. 点击跳转日记本列表
  3. 设置更新日记本信息
  4. 上拉刷新,下拉加载

列表信息展示

分析:

  1. 列表页数据是动态的,需要采用builder构建列表widget,同时每个列表数据需要单独显示,也就是需要分割线,所以使用separatorBuilder。这里选择使用ListView.separated来构建列表。
  2. 列表数据展示cell,这里将cell进行封装使用。

先来第一步,构建列表:

php 复制代码
body: ListView.separated(
      itemCount: dreamList.length,
      itemBuilder: (BuildContext context, int index){
      //封装的cell,将日记本数据模型传入
      return DreamListCell(dream: dreamList[index]);
      },
      separatorBuilder: (BuildContext context, int index){
      //分割线
          return const Divider(
          height: 1,
          color: SSLUIManager.dividerLight,
        );
      },
    ),

第二步和第三步一起,封装DreamListCell。

cell 中标题和副标题不确定长度,需要自适应显示,且最多仅显示两行。

less 复制代码
Widget build(BuildContext context) {
  return GestureDetector(//添加手势,点击cell进入日记列表
    child: Container(
        color: sslUI.cellBackColor,
        child: Column(
          children: [
            Padding(
              padding: const EdgeInsets.only(left: 15, top: 10, right: 15),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                //控制标题的高度
                  SizedBox(
                    height: 35,//获取当前屏幕的宽,右边留位置给更新按钮
                    width: MediaQuery.of(context).size.width - 80,
                    child: Text(dreamInfo.title, style: TextStyle(color: sslUI.mainText, fontSize: 16), maxLines: 2,overflow: TextOverflow.ellipsis,),//文本显示设置
                  ),
                  //控制按钮大小
                  SizedBox(
                    width: 40,
                    height: 40,
                    //右边更新按钮
                    child: IconButton(
                      alignment: Alignment.topRight,
                      padding: EdgeInsets.zero,
                        onPressed: ()async{
                        点击进入更新列表,更新完成后返回最新的日记本信息
                          dreamInfo = await Get.toNamed(SSLRoutes.home_add_dream,arguments: dreamInfo);
                          setState(() {

                          });
                        },
                        icon: Icon(Icons.settings, color: sslUI.iconColor,)
                    ),
                  ),
                ],
              ),
            ),
            //副标题和时间弹性显示
            Flex(
              direction: Axis.horizontal,
              children: [
                Expanded(
                  flex: 3,
                  child: Padding(
                    padding: const EdgeInsets.only(left: 15, top: 0, bottom: 10),
                    child: Text(dreamInfo.subTitle, style: TextStyle(color: sslUI.subText),maxLines: 2, overflow: TextOverflow.ellipsis,),
                  ),
                ),
                Expanded(
                    flex: 2,
                    child: Padding(
                      padding: const EdgeInsets.only(right: 15, top: 0, bottom: 10,left: 10),
                      child: Text(dreamInfo.getLastTimeStr(),textAlign: TextAlign.right, style: TextStyle(color: sslUI.subText),maxLines: 2,overflow: TextOverflow.clip,),
                    )
                ),
              ],
            ),
          ],
        )
    ),
    onTap: (){
    //手势单击进入日记列表
      clickAction();
    },
  );
}
void clickAction(){
  Get.toNamed(SSLRoutes.home_RecordList,arguments: dreamInfo.dreamId);
}

第四步,添加上拉刷新和下拉加载

这里采用三方库 easy_refresh来实现。 最终代码:

scss 复制代码
class SSLHomeState extends State <SSLHome> with AutomaticKeepAliveClientMixin{
  late EasyRefreshController  _easeController;
  late List<DreamModel> dreamList;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _easeController = EasyRefreshController(
      controlFinishLoad: true,
      controlFinishRefresh: true,
    );
    dreamList = [];
    loadDataAction();
  }

  @override
  bool get wantKeepAlive => true;
  @override
  Widget build(BuildContext context) {
    super.build(context);
    // TODO: implement build
    return Scaffold(
      // backgroundColor: sslUI.scrollBgColor,
      appBar: AppBar(
        title: Text(SSLLocales.main_tab_home.tr),
        actions: [
          IconButton(
              onPressed: () async{
                  int result = await Get.toNamed(SSLRoutes.home_add_dream, arguments: null);
                  debugPrint('ssl current $result');
                  if (result > 0){
                    loadDataAction();
                  }
              },
              icon: Icon(Icons.add_circle,color: sslUI.iconColor,)
          )
        ],
      ),
      body: EasyRefresh(
        onLoad: () async {
          // List<DreamModel> lists = await sslDB.selectDream();
          // debugPrint("Start refresh data $lists\n");
        },
        onRefresh: ()async {
          loadDataAction();
        },
        header: const ClassicHeader(),
        footer: const ClassicFooter(),
        child: ListView.separated(
          itemCount: dreamList.length,
          itemBuilder: (BuildContext context, int index){
              return DreamListCell(dream: dreamList[index]);
          },
          separatorBuilder: (BuildContext context, int index){
            return const Divider(
              height: 1,
              color: SSLUIManager.dividerLight,
            );
          },
        ),
      ),
    );
  }
  // Future<List<DreamModel>> 下拉加载数据
  void loadDataAction() async{
    List<DreamModel> lists = await sslDB.selectDream();
    debugPrint("Start load data $lists\n");
    dreamList = [];
    dreamList.insertAll(0, lists);
    setState(() {

    });
    // return lists;
  }

  @override
  void dispose() {
  //移除后销毁刷新控制器
    // TODO: implement dispose
    _easeController.dispose();
    super.dispose();
  }
}

最终效果:

相关推荐
迷雾漫步者1 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
coder_pig6 小时前
📝小记:Ubuntu 部署 Jenkins 打包 Flutter APK
flutter·ubuntu·jenkins
捡芝麻丢西瓜8 小时前
flutter自学笔记5- dart 编码规范
flutter·dart
恋猫de小郭8 小时前
什么?Flutter 可能会被 SwiftUI/ArkUI 化?全新的 Flutter Roadmap
flutter·ios·swiftui
网安墨雨12 小时前
iOS应用网络安全之HTTPS
web安全·ios·https
福大大架构师每日一题14 小时前
37.1 prometheus管理接口源码讲解
ios·iphone·prometheus
BangRaJun1 天前
LNCollectionView-替换幂率流体
算法·ios·设计
刘小哈哈哈1 天前
iOS 多个输入框弹出键盘处理
macos·ios·cocoa
靴子学长1 天前
iOS + watchOS Tourism App(含源码可简单复现)
mysql·ios·swiftui
sunly_1 天前
Flutter:导航,tab切换,顶部固定,列表分页滚动
开发语言·javascript·flutter