Flutter分类栏添加点击事件及对应内容切换实现咨询
Flutter分类栏点击切换内容实现方案
核心思路
要实现分类点击切换内容,需要状态管理记录当前选中的分类,再根据选中分类过滤并展示对应内容。具体步骤如下:
步骤1:将StatelessWidget改为StatefulWidget
因为需要维护选中状态和内容展示的变化,StatelessWidget无法保存状态,所以改成带状态的组件。
步骤2:添加状态变量
在状态类中定义两个关键变量:
selectedCategoryIndex:记录当前选中的分类索引,默认选中第一个(All)contentData:模拟不同分类对应的内容数据,可根据实际需求替换为真实数据
步骤3:为分类栏添加点击事件
用InkWell包裹分类的Container,点击时更新selectedCategoryIndex,同时通过颜色变化反馈选中状态。
步骤4:根据选中分类展示对应内容
根据selectedCategoryIndex过滤contentData,动态生成对应分类的内容项。
完整修改后的代码
import 'package:flutter/material.dart'; var category = [ 'All', 'Events', 'Activities', 'Restaurants', 'Malls', ]; // 模拟内容数据,每个item包含分类标识和展示内容 final List<Map<String, dynamic>> contentData = [ {'category': 'All', 'title': '全城热门推荐', 'color': Colors.deepPurple}, {'category': 'Events', 'title': '音乐节', 'color': Colors.orange}, {'category': 'Events', 'title': '艺术展览', 'color': Colors.orange}, {'category': 'Activities', 'title': '户外徒步', 'color': Colors.green}, {'category': 'Activities', 'title': '亲子乐园', 'color': Colors.green}, {'category': 'Restaurants', 'title': '海鲜餐厅', 'color': Colors.red}, {'category': 'Restaurants', 'title': '网红咖啡馆', 'color': Colors.red}, {'category': 'Malls', 'title': '购物广场A', 'color': Colors.blue}, {'category': 'Malls', 'title': '奥特莱斯', 'color': Colors.blue}, ]; class PostScreen1 extends StatefulWidget { @override State<PostScreen1> createState() => _PostScreen1State(); } class _PostScreen1State extends State<PostScreen1> { // 默认选中第一个分类(All) int selectedCategoryIndex = 0; @override Widget build(BuildContext context) { // 根据选中的分类过滤内容 List<Map<String, dynamic>> filteredContent = contentData.where((item) { if (selectedCategoryIndex == 0) { // 选中All时展示所有内容 return true; } return item['category'] == category[selectedCategoryIndex]; }).toList(); return Scaffold( body: SafeArea( child: CustomScrollView( slivers: [ SliverAppBar( backgroundColor: Colors.deepPurple, expandedHeight: 300, floating: false, pinned: true, flexibleSpace: FlexibleSpaceBar( title: const Text('Jubail'), background: Image.asset( 'assets/images/image1.jpg', fit: BoxFit.cover, ), ), ), // 分类栏 const SliverToBoxAdapter( child: SizedBox(height: 15), ), SliverToBoxAdapter( child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Padding( padding: const EdgeInsets.all(8), child: Row( children: [ for (int i = 0; i < category.length; i++) InkWell( onTap: () { // 点击时更新选中索引,触发UI重建 setState(() { selectedCategoryIndex = i; }); }, child: Container( margin: const EdgeInsets.symmetric(horizontal: 5), padding: const EdgeInsets.all(15), // 根据选中状态切换背景色 decoration: BoxDecoration( color: selectedCategoryIndex == i ? Colors.deepPurple : const Color.fromARGB(255, 126, 84, 199), borderRadius: BorderRadius.circular(14), boxShadow: [ BoxShadow( color: const Color.fromARGB(255, 247, 246, 248), blurRadius: 4, ), ], ), child: Text( category[i], style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: Colors.white, ), ), ), ), ], ), ), ), ), // 内容区域:根据过滤后的内容动态生成 SliverList( delegate: SliverChildBuilderDelegate( (context, index) { final item = filteredContent[index]; return Padding( padding: const EdgeInsets.all(15), child: ClipRRect( borderRadius: BorderRadius.circular(20), child: Container( height: 200, color: item['color'], child: Stack( children: [ Positioned( top: 10, right: 10, child: InkWell( onTap: () {}, child: Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( color: Colors.black26, blurRadius: 6, ), ], ), child: const Icon( Icons.favorite_border_outlined, color: Color.fromARGB(255, 53, 31, 142), size: 20, ), ), ), ), // 添加内容标题,方便区分不同分类的内容 Center( child: Text( item['title'], style: const TextStyle( fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold, ), ), ), ], ), ), ), ); }, childCount: filteredContent.length, ), ), ], ), ), ); } }
关键说明
- 状态管理:通过
setState更新选中索引,触发UI重新渲染,实现分类切换的视觉反馈和内容更新。 - 内容过滤:使用
where方法根据选中的分类过滤内容,选中All时展示全部内容。 - 交互反馈:分类按钮的背景色会随选中状态变化,让用户清晰知道当前选中的分类。
- 内容优化:把原本重复的内容改成
SliverList动态生成,更符合Flutter的性能优化原则,也方便维护。
内容的提问来源于stack exchange,提问作者Aljowharah Albader
相关产品推荐
相关产品推荐

