Flutter如何实现全局横向+纵向滚动的动态CheckboxListTile?
解决Flutter全局横向+纵向同步滚动的复选框列表问题
要实现所有条目同步横向、纵向滚动,核心是调整滚动容器的嵌套结构,让横向滚动容器包裹整个纵向列表,而非让每个条目独立处理溢出。以下是修改后的完整代码及关键说明:
修改后的代码
import 'package:flutter/material.dart'; import 'package:qhse_auto/common_ui/button/OutlineButtonTextOnly.dart'; import 'package:qhse_auto/common_ui/button/PrimaryButtonTextOnly.dart'; import 'package:qhse_auto/common_ui/empty_padding.dart'; import 'package:qhse_auto/common_ui/widgets/common_search_filter.dart'; import 'package:qhse_auto/common_ui/widgets/common_textfield.dart'; class PopupSelectUserWidget extends StatefulWidget { const PopupSelectUserWidget({super.key}); @override State<PopupSelectUserWidget> createState() => _PopupSelectUserWidgetState(); } class _PopupSelectUserWidgetState extends State<PopupSelectUserWidget> { bool isCheck = false; final List<int> shades = [100, 200, 300, 400, 500, 600, 700, 800, 900]; final ScrollController _horizontalScrollController = ScrollController(); final ScrollController _verticalScrollController = ScrollController(); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.only(left: 24, top: 20, right: 24, bottom: 16), child: Wrap( children: [ Container( width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.grey), ), child: Padding( padding: const EdgeInsets.all(12), child: Column( children: [ const CommonTextField( hint: 'Search NIK, Nama, Departemen, Jabatan', ), 12.ph, Container( padding: const EdgeInsets.only( left: 12, right: 12, top: 12, bottom: 12, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), border: Border.all( color: const Color(0XFF7F8895).withOpacity(0.30), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Anggota Team', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), const Divider( color: Color(0XFFE1E1E1), thickness: 1.5, ), 12.ph, SizedBox( height: MediaQuery.sizeOf(context).height / 2.5, width: double.infinity, child: Scrollbar( controller: _verticalScrollController, thumbVisibility: true, trackVisibility: true, child: Scrollbar( controller: _horizontalScrollController, thumbVisibility: true, trackVisibility: true, notificationPredicate: (notif) => notif.depth == 1, child: SingleChildScrollView( controller: _horizontalScrollController, scrollDirection: Axis.horizontal, child: SizedBox( width: MediaQuery.sizeOf(context).width, child: ListView.builder( controller: _verticalScrollController, shrinkWrap: true, itemCount: 40, itemBuilder: (context, index) { return CheckboxListTile( value: isCheck, onChanged: (value) { setState(() { isCheck = value!; }); }, title: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const CircleAvatar( backgroundImage: AssetImage('assets/images/ilham.jpeg'), ), 4.pw, RichText( text: const TextSpan( text: 'Ristu Aji W\n', style: TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500, ), children: [ TextSpan( text: '19786', style: TextStyle( color: Color(0XFF7F8895), fontSize: 16, fontWeight: FontWeight.w500, ), ), ], ), ), 24.pw, RichText( text: const TextSpan( text: 'Operation\n', style: TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500, ), children: [ TextSpan( text: 'Mobile Developersdsdsdsdsdsds', style: TextStyle( color: Color(0XFF7F8895), fontSize: 16, fontWeight: FontWeight.w500, ), ), ], ), ), ], ), ); }, ), ), ), ), ), ), ], ), ), Padding( padding: const EdgeInsets.symmetric(vertical: 16), child: Row( children: [ Expanded( child: OutlineButtonText( onTap: () { Navigator.pop(context); }, label: 'Cancel', ), ), const SizedBox(width: 16), Expanded( child: PrimaryButtonTextOnly( onTap: () { // goNext(context); }, label: 'Next', isActive: true, ), ), ], ), ) ], ), ), ) ], ), ); } }
关键修改说明
- 滚动容器嵌套顺序调整:将横向
SingleChildScrollView作为外层容器,包裹整个纵向ListView.builder,确保所有列表条目随横向滚动同步移动,而非单个条目独立处理溢出。 - 替换Column为ListView.builder:用
ListView.builder替代Column+List.generate,既高效处理大量列表项,又原生支持纵向滚动,无需额外嵌套SingleChildScrollView。 - 移除文本溢出截断:删除
RichText的overflow: TextOverflow.ellipsis,让完整文本显示,由外层横向滚动容器处理超出屏幕的内容。 - 滚动控制器绑定优化:明确横向控制器绑定外层横向滚动容器,纵向控制器绑定
ListView,确保滚动行为准确对应。
内容的提问来源于stack exchange,提问作者Ristu Mactavish
相关产品推荐
相关产品推荐

