You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

113 lines
3.2 KiB

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:win_text_editor/shared/components/text_editor.dart';
import 'package:win_text_editor/frame/widgets/tab_manager.dart';
import 'package:win_text_editor/frame/models/tab_model.dart';
import 'package:win_text_editor/modules/content_search/widgets/content_search_view.dart';
class TabView extends StatelessWidget {
final List<AppTab> tabs;
final String? currentTabId;
const TabView({super.key, required this.tabs, required this.currentTabId});
@override
Widget build(BuildContext context) {
final activeTab = tabs.firstWhere(
(tab) => tab.id == currentTabId,
orElse: () => AppTab(id: '', title: ''), // 提供默认值
);
return Column(
children: [
// 选项卡标签栏
_buildTabBar(context),
// 选项卡内容区
Expanded(
child:
activeTab.id.isNotEmpty
? _buildTabContent(activeTab)
: const Center(child: Text('无活动标签页')),
),
],
);
}
Widget _buildTabBar(BuildContext context) {
return SizedBox(
height: 40,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: tabs.length,
itemBuilder: (ctx, index) {
final tab = tabs[index];
return _TabItem(
tab: tab,
isActive: tab.id == currentTabId,
onClose: () => context.read<TabManager>().closeTab(tab.id),
onTap: () => context.read<TabManager>().setActiveTab(tab.id),
);
},
),
);
}
Widget _buildTabContent(AppTab tab) {
return IndexedStack(
index: tabs.indexWhere((tab) => tab.id == currentTabId).clamp(0, tabs.length - 1),
children:
tabs.map((tab) {
return findActiveView(tab);
}).toList(),
);
}
// 查找当前活动的视图
Widget findActiveView(AppTab tab) {
switch (tab.type) {
case 'content_search':
return ContentSearchView(tabId: tab.id);
default:
return TextEditor(tabId: tab.id, initialContent: tab.content);
}
}
}
class _TabItem extends StatelessWidget {
final AppTab tab;
final bool isActive;
final VoidCallback onClose;
final VoidCallback onTap;
const _TabItem({
required this.tab,
required this.isActive,
required this.onClose,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: isActive ? Colors.blue[100] : Colors.grey[200],
border: Border(
bottom: BorderSide(color: isActive ? Colors.blue : Colors.transparent, width: 2),
),
),
child: Row(
children: [
if (tab.icon != null) Icon(tab.icon, size: 16),
if (tab.icon != null) const SizedBox(width: 4),
Text(tab.title),
const SizedBox(width: 8),
IconButton(icon: const Icon(Icons.close, size: 16), onPressed: onClose),
],
),
),
);
}
}