feat:更新TabUI模块

This commit is contained in:
2025-11-18 11:46:21 +08:00
parent 21ff0ad94f
commit df26790389
9 changed files with 88 additions and 47 deletions

View File

@@ -1,9 +1,18 @@
import 'package:flutter/material.dart';
import 'package:food_hub_app/widgets/common/index.dart';
import 'package:food_hub_app/widgets/recipe/calendar.dart';
import 'package:food_hub_app/widgets/recipe/list.dart';
import 'package:food_hub_app/widgets/recipe/timeline.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
enum RecordTab {
recipe('菜谱'),
calendar('日历'),
timeline('时间轴');
final String label;
const RecordTab(this.label);
}
class RecordPage extends StatefulWidget {
const RecordPage({super.key});
@@ -12,51 +21,46 @@ class RecordPage extends StatefulWidget {
State<StatefulWidget> createState() => _RecordPageState();
}
class _RecordPageState extends State<RecordPage>
with SingleTickerProviderStateMixin {
late final TabController _tabController = TabController(
length: 3,
vsync: this,
);
final List<TDTab> tabs = [
const TDTab(text: '菜谱', icon: Icon(Icons.book)),
const TDTab(text: '日历', icon: Icon(Icons.calendar_month)),
const TDTab(text: '时间轴', icon: Icon(Icons.timeline)),
class _RecordPageState extends State<RecordPage> {
RecordTab _currentTab = RecordTab.recipe;
final List<Widget> _tabPages = [
RecipeList(),
RecipeCalendar(),
RecipeTimeline(),
];
@override
void initState() {
super.initState();
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
Widget buildTabs({
required BuildContext context,
required RecordTab currentTab,
required ValueChanged<RecordTab> onTabChanged,
}) {
return Container(
padding: EdgeInsets.all(8),
child: buildToggleSwitch(
context: context,
currentTab: currentTab,
tabValues: RecordTab.values,
labels: RecordTab.values.map((e) => e.label).toList(),
onTabChanged: onTabChanged,
),
);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TDTabBar(
tabs: tabs,
controller: _tabController,
backgroundColor: Colors.white,
showIndicator: true,
buildTabs(
context: context,
currentTab: _currentTab,
onTabChanged: (tab) {
setState(() {
_currentTab = tab;
});
},
),
SizedBox(height: 8),
Expanded(
child: TabBarView(
controller: _tabController,
children: [
RecipeList(),
RecipeCalendar(),
RecipeTimeline(),
],
),
child: IndexedStack(index: _currentTab.index, children: _tabPages),
),
],
);

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:toggle_switch/toggle_switch.dart';
Widget formLabelText({required String labelText, bool isRequired = false}) {
return Text.rich(
@@ -50,16 +51,46 @@ Widget buildEmptyData() {
);
}
Widget buildToggleSwitch<T extends Enum>({
required BuildContext context,
required T currentTab,
required List<T> tabValues,
required List<String> labels,
required ValueChanged<T> onTabChanged,
}) {
return ToggleSwitch(
minWidth: 90.0,
minHeight: 40.0,
initialLabelIndex: tabValues.indexOf(currentTab),
totalSwitches: tabValues.length,
labels: labels,
activeBgColor: [Theme.of(context).colorScheme.primary],
activeFgColor: Colors.white,
inactiveBgColor: Colors.grey.shade200,
inactiveFgColor: Colors.grey.shade700,
cornerRadius: 12.0,
customTextStyles: [TextStyle(fontSize: 12, fontWeight: FontWeight.w500)],
onToggle: (index) {
if (index != null && index < tabValues.length) {
onTabChanged(tabValues[index]);
}
},
);
}
/// 圆形图标按钮
Widget circleIconButton({
required IconData icon,
required VoidCallback onPressed,
required BuildContext context,
bool? isSmall
}) {
final double size = isSmall == true ? 24 : 36;
return ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
fixedSize: Size(26, 26),
fixedSize: Size(size, size),
shape: CircleBorder(),
elevation: 0,
backgroundColor: Theme.of(context).colorScheme.primary,

View File

@@ -91,6 +91,7 @@ class _YearSelectorState extends State<YearSelector>
circleIconButton(
context: context,
icon: Icons.chevron_left,
isSmall: true,
onPressed: () => _previousYear(),
),
SizedBox(width: 5),
@@ -113,6 +114,7 @@ class _YearSelectorState extends State<YearSelector>
circleIconButton(
context: context,
icon: Icons.chevron_right,
isSmall: true,
onPressed: () => _nextYear(),
)
],

View File

@@ -114,13 +114,13 @@ class _RecipeCalendarState extends State<RecipeCalendar> {
return Card(
elevation: 0,
color: colors.inversePrimary,
color: colors.onSecondary,
child: Padding(
padding: EdgeInsets.all(10),
child: Row(
children: [
CircleAvatar(
radius: 24,
radius: 20,
backgroundColor: colors.primary,
child: Text(
record.category[0],

View File

@@ -39,7 +39,7 @@ class RecipeCard extends StatelessWidget {
icon: Icons.edit,
onPressed: () => {},
),
SizedBox(width: 8),
SizedBox(width: 4),
circleIconButton(
context: context,
icon: Icons.book,
@@ -54,7 +54,6 @@ class RecipeCard extends StatelessWidget {
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,

View File

@@ -33,14 +33,11 @@ class _RecipeListState extends State<RecipeList> {
if (recipeSummaryList.isEmpty) {
return buildEmptyData();
} else {
return ListView.separated(
return ListView.builder(
itemCount: recipeSummaryList.length,
itemBuilder: (context, index) {
return RecipeCard(recipe: recipeSummaryList[index]);
},
separatorBuilder: (context, index) {
return SizedBox(height: 10);
},
}
);
}
}

View File

@@ -5,7 +5,6 @@ import 'package:food_hub_app/models/recipe.dart';
import 'package:food_hub_app/widgets/common/image.dart';
import 'package:food_hub_app/widgets/common/index.dart';
import 'package:food_hub_app/widgets/common/year_selector.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'package:timelines_plus/timelines_plus.dart';
class RecipeTimeline extends StatefulWidget {

View File

@@ -906,6 +906,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.2"
toggle_switch:
dependency: "direct main"
description:
name: toggle_switch
sha256: dca04512d7c23ed320d6c5ede1211a404f177d54d353bf785b07d15546a86ce5
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.0"
typed_data:
dependency: transitive
description:

View File

@@ -38,6 +38,7 @@ dependencies:
dio: ^5.7.0
timelines_plus: ^1.0.7
table_calendar: ^3.1.3
toggle_switch: ^2.3.0
flutter_form_builder: ^10.0.0
form_builder_validators: ^11.1.2
intl: ^0.19.0