|
|
@ -1,34 +1,33 @@ |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:provider/provider.dart'; |
|
|
|
import 'package:provider/provider.dart'; |
|
|
|
|
|
|
|
import 'package:win_text_editor/modules/content_search/controllers/content_search_controller.dart'; |
|
|
|
import 'package:win_text_editor/shared/components/text_editor.dart'; |
|
|
|
import 'package:win_text_editor/shared/components/text_editor.dart'; |
|
|
|
import 'package:win_text_editor/framework/controllers/tab_manager.dart'; |
|
|
|
import 'package:win_text_editor/framework/controllers/tab_manager.dart'; |
|
|
|
import 'package:win_text_editor/framework/models/tab_model.dart'; |
|
|
|
import 'package:win_text_editor/framework/models/tab_model.dart'; |
|
|
|
import 'package:win_text_editor/modules/content_search/widgets/content_search_view.dart'; |
|
|
|
import 'package:win_text_editor/modules/content_search/widgets/content_search_view.dart'; |
|
|
|
|
|
|
|
|
|
|
|
class TabView extends StatelessWidget { |
|
|
|
class TabView extends StatefulWidget { |
|
|
|
final List<AppTab> tabs; |
|
|
|
final List<AppTab> tabs; |
|
|
|
final String? currentTabId; |
|
|
|
final String? currentTabId; |
|
|
|
|
|
|
|
|
|
|
|
const TabView({super.key, required this.tabs, required this.currentTabId}); |
|
|
|
const TabView({super.key, required this.tabs, required this.currentTabId}); |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
Widget build(BuildContext context) { |
|
|
|
State<TabView> createState() => _TabViewState(); |
|
|
|
final activeTab = tabs.firstWhere( |
|
|
|
} |
|
|
|
(tab) => tab.id == currentTabId, |
|
|
|
|
|
|
|
orElse: () => AppTab(id: '', title: ''), // 提供默认值 |
|
|
|
class _TabViewState extends State<TabView> { |
|
|
|
); |
|
|
|
// 缓存已创建的视图 |
|
|
|
|
|
|
|
final Map<String, Widget> _viewCache = {}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
|
|
|
Widget build(BuildContext context) { |
|
|
|
return Column( |
|
|
|
return Column( |
|
|
|
children: [ |
|
|
|
children: [ |
|
|
|
// 选项卡标签栏 |
|
|
|
// 选项卡标签栏 |
|
|
|
_buildTabBar(context), |
|
|
|
_buildTabBar(context), |
|
|
|
// 选项卡内容区 |
|
|
|
// 选项卡内容区 |
|
|
|
Expanded( |
|
|
|
Expanded(child: _buildTabContent()), |
|
|
|
child: |
|
|
|
|
|
|
|
activeTab.id.isNotEmpty |
|
|
|
|
|
|
|
? _buildTabContent(activeTab) |
|
|
|
|
|
|
|
: const Center(child: Text('无活动标签页')), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
], |
|
|
|
], |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
@ -38,12 +37,12 @@ class TabView extends StatelessWidget { |
|
|
|
height: 40, |
|
|
|
height: 40, |
|
|
|
child: ListView.builder( |
|
|
|
child: ListView.builder( |
|
|
|
scrollDirection: Axis.horizontal, |
|
|
|
scrollDirection: Axis.horizontal, |
|
|
|
itemCount: tabs.length, |
|
|
|
itemCount: widget.tabs.length, |
|
|
|
itemBuilder: (ctx, index) { |
|
|
|
itemBuilder: (ctx, index) { |
|
|
|
final tab = tabs[index]; |
|
|
|
final tab = widget.tabs[index]; |
|
|
|
return _TabItem( |
|
|
|
return _TabItem( |
|
|
|
tab: tab, |
|
|
|
tab: tab, |
|
|
|
isActive: tab.id == currentTabId, |
|
|
|
isActive: tab.id == widget.currentTabId, |
|
|
|
onClose: () => context.read<TabManager>().closeTab(tab.id), |
|
|
|
onClose: () => context.read<TabManager>().closeTab(tab.id), |
|
|
|
onTap: () => context.read<TabManager>().setActiveTab(tab.id), |
|
|
|
onTap: () => context.read<TabManager>().setActiveTab(tab.id), |
|
|
|
); |
|
|
|
); |
|
|
@ -52,16 +51,30 @@ class TabView extends StatelessWidget { |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Widget _buildTabContent(AppTab tab) { |
|
|
|
Widget _buildTabContent() { |
|
|
|
|
|
|
|
final tabManager = Provider.of<TabManager>(context, listen: false); |
|
|
|
|
|
|
|
final activeIndex = widget.tabs.indexWhere((t) => t.id == widget.currentTabId); |
|
|
|
|
|
|
|
if (activeIndex == -1) return const Center(child: Text('无活动标签页')); |
|
|
|
|
|
|
|
|
|
|
|
return IndexedStack( |
|
|
|
return IndexedStack( |
|
|
|
index: tabs.indexWhere((tab) => tab.id == currentTabId).clamp(0, tabs.length - 1), |
|
|
|
index: activeIndex, |
|
|
|
children: |
|
|
|
children: |
|
|
|
tabs.map((tab) { |
|
|
|
widget.tabs.map((tab) { |
|
|
|
return findActiveView(tab); |
|
|
|
final controller = tabManager.getController<ContentSearchController>(tab.id); |
|
|
|
|
|
|
|
return KeyedSubtree(key: ValueKey(tab.id), child: _buildTabItem(tab, controller)); |
|
|
|
}).toList(), |
|
|
|
}).toList(), |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Widget _buildTabItem(AppTab tab, ContentSearchController? controller) { |
|
|
|
|
|
|
|
switch (tab.type) { |
|
|
|
|
|
|
|
case 'content_search': |
|
|
|
|
|
|
|
return ContentSearchView(tabId: tab.id, controller: controller); |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
return TextEditor(tabId: tab.id, initialContent: tab.content); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 查找当前活动的视图 |
|
|
|
// 查找当前活动的视图 |
|
|
|
Widget findActiveView(AppTab tab) { |
|
|
|
Widget findActiveView(AppTab tab) { |
|
|
|
switch (tab.type) { |
|
|
|
switch (tab.type) { |
|
|
|