Flutter:竖向步骤条,类似查看物流组件

工作中写到了一个类似步骤条的样式,记录一下, 抽空将其改成发货查看物流模板。

页面

js 复制代码
import 'package:dogex/common/index.dart';
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';

import 'index.dart';

class NewsListPage extends GetView<NewsListController> {
  const NewsListPage({super.key});

  // 时间
  Widget _buildTime() {
    return <Widget>[
      TDImage(assetUrl: 'assets/img/home4.png',width: 48.w,height: 48.w,),
      SizedBox(width: 10.w,),
      TextWidget.body('2/06',size: 40.sp,color: AppTheme.colorfff,weight: FontWeight.w600),
      SizedBox(width: 15.w,),
      TextWidget.body('星期四',size: 24.sp,color: AppTheme.color6C7481,weight: FontWeight.w600),
    ].toRow();
  }

  // 列表
  Widget _buildList() {
    return SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) {
          return IntrinsicHeight(
            child: <Widget>[
              // 左边圆圈
              <Widget>[
                <Widget>[].toRow().tight(width: 14.w,height: 14.w)
                .border(all: 2,color: AppTheme.colorfff)
                .backgroundColor(AppTheme.blockBgColor)
                .clipRRect(all: 7.w),
                Expanded(
                  child: TDDivider(width: 1,color: AppTheme.colorfff,),
                )
              ].toColumn(),
              // 右边文章内容
              <Widget>[
                // 时间
                TextWidget.body('11:21',size: 24.sp,color: AppTheme.color666,),
                SizedBox(height: 20.w),
                // 标题
                TextWidget.body('美国两家律师事务所起诉Pump.fun',size: 26.sp,color: AppTheme.colorfff,),
                SizedBox(height: 30.w),
                // 内容
                TextWidget.body(
                  index == 0 ?
                  '金色财经报道,据 Cointelegraph 报道,Pump.fun 因涉嫌使用两家律师事务所的标志和名称而收到一封停止令,这两家律师事务所目前正在起诉该平台。美国律师事务所 Bunwick Law 在 X平台的声明中表示,该公司和 WolfPopper 已向 Pump.fun 发出了一封停止令,要求"立即删除"Dog Shit Going NoWhere(DOGSHIT2)和其他代币这些代币通过未经许可使用知识产权(包括其徽标和名称)"冒充了我们的公司"。据 Pump.fun称,多名用户以各种配置使用Burwick Law和Wolf Popper的名称和微标创建了代币。还有一些代币使用了Burwick Law员工和其在针对Pump.fun的诉讼中的一名客户的姓名和肖像。'
                  : '其他内容',
                  size: 24.sp,color: AppTheme.color999,
                ),
                SizedBox(height: 30.w),
                // 查看原文
                TextWidget.body('查看原文',size: 24.sp,color: AppTheme.primaryBlue,textAlign: TextAlign.end,).width(650.w),
                SizedBox(height: 60.w),
              ].toColumn(crossAxisAlignment: CrossAxisAlignment.start).width(650.w),
            ].toRow(mainAxisAlignment: MainAxisAlignment.spaceBetween,crossAxisAlignment: CrossAxisAlignment.start),
          );
        },
        childCount: 10,
      ),
    );
  }

  // 主视图
  Widget _buildView() {
    return CustomScrollView(
      slivers: [
        SizedBox(height: 30.w).sliverToBoxAdapter(),
        _buildTime().sliverToBoxAdapter().sliverPaddingHorizontal(30.w),
        SizedBox(height: 30.w).sliverToBoxAdapter(),
        _buildList().sliverPaddingHorizontal(30.w),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return GetBuilder<NewsListController>(
      init: NewsListController(),
      id: "news_list",
      builder: (_) {
        return Scaffold(
          backgroundColor: AppTheme.pageBgColor, // 自定义颜色
          appBar: TDNavBar(
            height: 44,
            title: '资讯',
            titleColor: AppTheme.colorfff,
            titleFontWeight: FontWeight.w600,
            backgroundColor: AppTheme.navBgColor,
            screenAdaptation: true,
            useDefaultBack: false,
            leftBarItems: [
              TDNavBarItem(icon: TDIcons.chevron_left, iconSize: 24, iconColor: AppTheme.colorfff,action: (){
                Get.back();
              }),
            ],
          ),
          body: SmartRefresher(
            controller: controller.refreshController,
            enablePullUp: true, // 启用上拉加载
            onRefresh: controller.onRefresh, // 下拉刷新回调
            onLoading: controller.onLoading, // 上拉加载回调
            footer: SmartRefresherFooterWidget(textColor: AppTheme.colorfff,), // 底部加载更多组件
            header: SmartRefresherHeaderWidget(textColor: AppTheme.colorfff,), // 头部刷新组件
            child: _buildView()
          )
        );
      },
    );
  }
}

控制器

js 复制代码
import 'package:get/get.dart';
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
// import 'package:dogex/common/index.dart';

class NewsListController extends GetxController {
  NewsListController();

  // 查看详情
  void goNewsDetail(String id) {
    Get.toNamed('/newsDetail',arguments: {'id': id});
  }

  List items = [];

  /*
  * 分页
  * */
  final RefreshController refreshController = RefreshController(
    initialRefresh: true,
  );
  // int _page = 1;
  Future<bool> _loadNewsSell(bool isRefresh) async {
    return false;
    // var result = await HomeApi.noticesList(PageListReq(
    //   pageNo:isRefresh ? 1:_page,
    //   pageSize:20
    // ));
    // if(isRefresh){
    //   _page = 1;
    //   items.clear();
    // }
    // if(result.isNotEmpty){
    //   _page++;
    //   items.addAll(result);
    // }
    // // 是否是空
    // return result.isEmpty;
  }

  // 上拉载入新商品
  void onLoading() async {
    if (items.isNotEmpty) {
      try {
        // 拉取数据是否为空 ? 设置暂无数据 : 加载完成
        var isEmpty = await _loadNewsSell(false);
        isEmpty
            ? refreshController.loadNoData()
            : refreshController.loadComplete();
      } catch (e) {
        refreshController.loadFailed(); // 加载失败
      }
    } else {
      refreshController.loadNoData(); // 设置无数据
    }
    update(["news_list"]);
  }

  // 下拉刷新
  void onRefresh() async {
    try {
      await _loadNewsSell(true);
      refreshController.refreshCompleted();
    } catch (e) {
      refreshController.refreshFailed();
    }
    update(["news_list"]);
  }



  _initData() {
    update(["news_list"]);
  }


  @override
  void onReady() {
    super.onReady();
    _initData();
  }

  @override
  void onClose() {
    super.onClose();
    refreshController.dispose();
  }
}
相关推荐
逍遥咸鱼3 小时前
Flutter文本框添加图片表情(粗制滥造版)
flutter
程序员老刘4 小时前
Flutter 官方Skill发布,对开发者意味着什么?
flutter·ai编程·客户端
血色橄榄枝5 小时前
20 Flutter for OpenHarmony 动画效果
flutter·开源·鸿蒙
Swift社区6 小时前
Flutter 项目如何做好性能监控与问题定位?
flutter
LawrenceLan6 小时前
36.Flutter 零基础入门(三十六):StatefulWidget 与 setState 进阶 —— 动态页面必学
开发语言·前端·flutter·dart
weixin_443478516 小时前
flutter组件学习之Stack 组件详解
学习·flutter
程序员Ctrl喵6 小时前
分层架构的协同艺术——解构 Flutter 的心脏
flutter·架构
Hello.Reader6 小时前
Flutter IM 桌面端消息发送、ACK 回执、SQLite 本地缓存与断线重连设计
flutter·缓存·sqlite
Hello.Reader6 小时前
Flutter IM 桌面端项目架构、聊天窗口布局与 WebSocket 长连接设计
websocket·flutter·架构
前端不太难6 小时前
Flutter Web / Desktop 为什么“能跑但不好用”?
前端·flutter·状态模式