import 'package:flutter/material.dart'; class ApplicationPage extends StatelessWidget { const ApplicationPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final List> buttonInfos = [ { 'title': '隐患排查', 'list': [ {'icon': 'assets/icon-apps/icon-zl-6.png', 'title': '隐患排查', 'num': 0}, {'icon': 'assets/icon-apps/icon-pc-1.png', 'title': '隐患快报', 'num': 2}, {'icon': 'assets/icon-apps/icon-zl-2.png', 'title': '检查记录', 'num': 0}, ], }, { 'title': '隐患治理', 'list': [ {'icon': 'assets/icon-apps/icon-zl-2.png', 'title': '隐患记录', 'num': 1}, { 'icon': 'assets/icon-apps/icon-zl-3.png', 'title': '待整改隐患', 'num': 3, }, { 'icon': 'assets/icon-apps/icon-zl-4.png', 'title': '超期未整改', 'num': 0, }, {'icon': 'assets/icon-apps/icon-yh-1.png', 'title': '隐患验收', 'num': 2}, { 'icon': 'assets/icon-apps/icon-zl-1.png', 'title': '已验收隐患', 'num': 0, }, ], }, { 'title': '专项检查', 'list': [ {'icon': 'assets/icon-apps/icon-pc-1.png', 'title': '隐患整改', 'num': 5}, {'icon': 'assets/icon-apps/icon-zl-2.png', 'title': '隐患记录', 'num': 0}, ], }, { 'title': '监管帮扶', 'list': [ {'icon': 'assets/icon-apps/icon-pc-1.png', 'title': '隐患整改', 'num': 2}, {'icon': 'assets/icon-apps/icon-zl-2.png', 'title': '隐患记录', 'num': 0}, ], }, ]; return Scaffold( body: ListView.builder( physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.all(0), itemCount: buttonInfos.length + 1, itemBuilder: (context, index) { // 第一项显示顶部图片 if (index == 0) { return ClipRRect( child: Image.asset( 'assets/images/apps-banner.jpg', fit: BoxFit.cover, ), ); } // 后续显示各 section final section = buttonInfos[index - 1]; final items = section['list'] as List; return Padding( padding: const EdgeInsets.only(top: 10), child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Section title Padding( padding: const EdgeInsets.fromLTRB(10, 10, 10, 5), child: Row( children: [ Container(width: 2, height: 10, color: Colors.blue), const SizedBox(width: 5), Text( section['title'] as String, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.bold, ), ), ], ), ), // Items wrap Padding( padding: const EdgeInsets.all(10), child: LayoutBuilder( builder: (context, constraints) { const spacing = 10.0; // 4 items per row final totalWidth = constraints.maxWidth; final itemWidth = (totalWidth - spacing * 3) / 4; return Wrap( spacing: spacing, runSpacing: spacing, children: items.map((item) { return SizedBox( width: itemWidth, child: _buildItem(item), ); }).toList(), ); }, ), ), ], ), ), ); }, ), ); } Widget _buildItem(Map item) { const double size = 60; final int badgeNum = item['num'] as int; return SizedBox( width: size, child: Column( mainAxisSize: MainAxisSize.min, children: [ // Image with badge overlay Stack( clipBehavior: Clip.none, children: [ SizedBox( width: 30, height: 30, child: Image.asset(item['icon'] as String, fit: BoxFit.contain), ), if (badgeNum > 0) Positioned( top: -5, right: -10, child: Container( width: 16, height: 16, decoration: const BoxDecoration( color: Colors.red, shape: BoxShape.circle, ), alignment: Alignment.center, child: Text( badgeNum.toString(), style: const TextStyle(color: Colors.white, fontSize: 10), ), ), ), ], ), const SizedBox(height: 4), Text( item['title'] as String, style: const TextStyle(fontSize: 12), textAlign: TextAlign.center, ), ], ), ); } }