Merge pull request #1186 from Kingtous/flutter_desktop
fix: tabbar rebuild issue
This commit is contained in:
		
						commit
						043a3e5f34
					
				| @ -7,7 +7,6 @@ import 'package:flutter_hbb/consts.dart'; | |||||||
| import 'package:flutter_hbb/desktop/pages/remote_page.dart'; | import 'package:flutter_hbb/desktop/pages/remote_page.dart'; | ||||||
| import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart'; | import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart'; | ||||||
| import 'package:flutter_hbb/utils/multi_window_manager.dart'; | import 'package:flutter_hbb/utils/multi_window_manager.dart'; | ||||||
| import 'package:provider/provider.dart'; |  | ||||||
| import 'package:get/get.dart'; | import 'package:get/get.dart'; | ||||||
| 
 | 
 | ||||||
| import '../../models/model.dart'; | import '../../models/model.dart'; | ||||||
| @ -22,11 +21,14 @@ class ConnectionTabPage extends StatefulWidget { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class _ConnectionTabPageState extends State<ConnectionTabPage> | class _ConnectionTabPageState extends State<ConnectionTabPage> | ||||||
|     with SingleTickerProviderStateMixin { |     with TickerProviderStateMixin { | ||||||
|   // refactor List<int> when using multi-tab |   // refactor List<int> when using multi-tab | ||||||
|   // this singleton is only for test |   // this singleton is only for test | ||||||
|   List<String> connectionIds = List.empty(growable: true); |   var connectionIds = RxList.empty(growable: true); | ||||||
|   var initialIndex = 0; |   var initialIndex = 0; | ||||||
|  |   late Rx<TabController> tabController; | ||||||
|  | 
 | ||||||
|  |   var connectionMap = RxList<Widget>.empty(growable: true); | ||||||
| 
 | 
 | ||||||
|   _ConnectionTabPageState(Map<String, dynamic> params) { |   _ConnectionTabPageState(Map<String, dynamic> params) { | ||||||
|     if (params['id'] != null) { |     if (params['id'] != null) { | ||||||
| @ -37,26 +39,27 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> | |||||||
|   @override |   @override | ||||||
|   void initState() { |   void initState() { | ||||||
|     super.initState(); |     super.initState(); | ||||||
|  |     tabController = | ||||||
|  |         TabController(length: connectionIds.length, vsync: this).obs; | ||||||
|     rustDeskWinManager.setMethodHandler((call, fromWindowId) async { |     rustDeskWinManager.setMethodHandler((call, fromWindowId) async { | ||||||
|       print( |       print( | ||||||
|           "call ${call.method} with args ${call.arguments} from window ${fromWindowId}"); |           "call ${call.method} with args ${call.arguments} from window ${fromWindowId}"); | ||||||
|       // for simplify, just replace connectionId |       // for simplify, just replace connectionId | ||||||
|       if (call.method == "new_remote_desktop") { |       if (call.method == "new_remote_desktop") { | ||||||
|         setState(() { |         final args = jsonDecode(call.arguments); | ||||||
|           final args = jsonDecode(call.arguments); |         final id = args['id']; | ||||||
|           final id = args['id']; |         final indexOf = connectionIds.indexOf(id); | ||||||
|           final indexOf = connectionIds.indexOf(id); |         if (indexOf >= 0) { | ||||||
|           if (indexOf >= 0) { |           initialIndex = indexOf; | ||||||
|             setState(() { |           tabController.value.animateTo(initialIndex, duration: Duration.zero); | ||||||
|               initialIndex = indexOf; |         } else { | ||||||
|             }); |           connectionIds.add(id); | ||||||
|           } else { |           initialIndex = connectionIds.length - 1; | ||||||
|             connectionIds.add(id); |           tabController.value = TabController( | ||||||
|             setState(() { |               length: connectionIds.length, | ||||||
|               initialIndex = connectionIds.length - 1; |               vsync: this, | ||||||
|             }); |               initialIndex: initialIndex); | ||||||
|           } |         } | ||||||
|         }); |  | ||||||
|       } else if (call.method == "onDestroy") { |       } else if (call.method == "onDestroy") { | ||||||
|         print("executing onDestroy hook, closing ${connectionIds}"); |         print("executing onDestroy hook, closing ${connectionIds}"); | ||||||
|         connectionIds.forEach((id) { |         connectionIds.forEach((id) { | ||||||
| @ -72,55 +75,52 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> | |||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     final tabBar = TabBar( |  | ||||||
|         isScrollable: true, |  | ||||||
|         labelColor: Colors.white, |  | ||||||
|         physics: NeverScrollableScrollPhysics(), |  | ||||||
|         indicatorColor: Colors.white, |  | ||||||
|         tabs: connectionIds |  | ||||||
|             .map((e) => Tab( |  | ||||||
|                   child: Row( |  | ||||||
|                     mainAxisSize: MainAxisSize.min, |  | ||||||
|                     crossAxisAlignment: CrossAxisAlignment.center, |  | ||||||
|                     children: [ |  | ||||||
|                       Text(e), |  | ||||||
|                       SizedBox( |  | ||||||
|                         width: 4, |  | ||||||
|                       ), |  | ||||||
|                       InkWell( |  | ||||||
|                           onTap: () { |  | ||||||
|                             onRemoveId(e); |  | ||||||
|                           }, |  | ||||||
|                           child: Icon( |  | ||||||
|                             Icons.highlight_remove, |  | ||||||
|                             size: 20, |  | ||||||
|                           )) |  | ||||||
|                     ], |  | ||||||
|                   ), |  | ||||||
|                 )) |  | ||||||
|             .toList()); |  | ||||||
|     final tabBarView = TabBarView( |  | ||||||
|         children: connectionIds |  | ||||||
|             .map((e) => Container( |  | ||||||
|                     child: RemotePage( |  | ||||||
|                   key: ValueKey(e), |  | ||||||
|                   id: e, |  | ||||||
|                   tabBarHeight: kDesktopRemoteTabBarHeight, |  | ||||||
|                 ))) //RemotePage(key: ValueKey(e), id: e)) |  | ||||||
|             .toList()); |  | ||||||
|     return Scaffold( |     return Scaffold( | ||||||
|       body: DefaultTabController( |       body: Column( | ||||||
|         initialIndex: initialIndex, |         children: [ | ||||||
|         length: connectionIds.length, |           DesktopTitleBar( | ||||||
|         animationDuration: Duration.zero, |             child: Container( | ||||||
|         child: Column( |                 height: kDesktopRemoteTabBarHeight, | ||||||
|           children: [ |                 child: Obx(() => TabBar( | ||||||
|             DesktopTitleBar( |                     isScrollable: true, | ||||||
|               child: Container(height: kDesktopRemoteTabBarHeight, child: tabBar), |                     labelColor: Colors.white, | ||||||
|             ), |                     physics: NeverScrollableScrollPhysics(), | ||||||
|             Expanded(child: tabBarView), |                     indicatorColor: Colors.white, | ||||||
|           ], |                     controller: tabController.value, | ||||||
|         ), |                     tabs: connectionIds | ||||||
|  |                         .map((e) => Tab( | ||||||
|  |                               child: Row( | ||||||
|  |                                 mainAxisSize: MainAxisSize.min, | ||||||
|  |                                 crossAxisAlignment: CrossAxisAlignment.center, | ||||||
|  |                                 children: [ | ||||||
|  |                                   Text(e), | ||||||
|  |                                   SizedBox( | ||||||
|  |                                     width: 4, | ||||||
|  |                                   ), | ||||||
|  |                                   InkWell( | ||||||
|  |                                       onTap: () { | ||||||
|  |                                         onRemoveId(e); | ||||||
|  |                                       }, | ||||||
|  |                                       child: Icon( | ||||||
|  |                                         Icons.highlight_remove, | ||||||
|  |                                         size: 20, | ||||||
|  |                                       )) | ||||||
|  |                                 ], | ||||||
|  |                               ), | ||||||
|  |                             )) | ||||||
|  |                         .toList()))), | ||||||
|  |           ), | ||||||
|  |           Expanded( | ||||||
|  |               child: Obx(() => TabBarView( | ||||||
|  |                   controller: tabController.value, | ||||||
|  |                   children: connectionIds | ||||||
|  |                       .map((e) => RemotePage( | ||||||
|  |                             key: ValueKey(e), | ||||||
|  |                             id: e, | ||||||
|  |                             tabBarHeight: kDesktopRemoteTabBarHeight, | ||||||
|  |                           )) //RemotePage(key: ValueKey(e), id: e)) | ||||||
|  |                       .toList()))), | ||||||
|  |         ], | ||||||
|       ), |       ), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| @ -130,9 +130,9 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> | |||||||
|     if (indexOf == -1) { |     if (indexOf == -1) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     setState(() { |     connectionIds.removeAt(indexOf); | ||||||
|       connectionIds.removeAt(indexOf); |     initialIndex = max(0, initialIndex - 1); | ||||||
|       initialIndex = max(0, initialIndex - 1); |     tabController.value = TabController( | ||||||
|     }); |         length: connectionIds.length, vsync: this, initialIndex: initialIndex); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -20,11 +20,12 @@ class FileManagerTabPage extends StatefulWidget { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class _FileManagerTabPageState extends State<FileManagerTabPage> | class _FileManagerTabPageState extends State<FileManagerTabPage> | ||||||
|     with SingleTickerProviderStateMixin { |     with TickerProviderStateMixin { | ||||||
|   // refactor List<int> when using multi-tab |   // refactor List<int> when using multi-tab | ||||||
|   // this singleton is only for test |   // this singleton is only for test | ||||||
|   var connectionIds = List<String>.empty(growable: true).obs; |   var connectionIds = List<String>.empty(growable: true).obs; | ||||||
|   var initialIndex = 0.obs; |   var initialIndex = 0; | ||||||
|  |   late Rx<TabController> tabController; | ||||||
| 
 | 
 | ||||||
|   _FileManagerTabPageState(Map<String, dynamic> params) { |   _FileManagerTabPageState(Map<String, dynamic> params) { | ||||||
|     if (params['id'] != null) { |     if (params['id'] != null) { | ||||||
| @ -35,6 +36,8 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> | |||||||
|   @override |   @override | ||||||
|   void initState() { |   void initState() { | ||||||
|     super.initState(); |     super.initState(); | ||||||
|  |     tabController = | ||||||
|  |         TabController(length: connectionIds.length, vsync: this).obs; | ||||||
|     rustDeskWinManager.setMethodHandler((call, fromWindowId) async { |     rustDeskWinManager.setMethodHandler((call, fromWindowId) async { | ||||||
|       print( |       print( | ||||||
|           "call ${call.method} with args ${call.arguments} from window ${fromWindowId}"); |           "call ${call.method} with args ${call.arguments} from window ${fromWindowId}"); | ||||||
| @ -44,10 +47,15 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> | |||||||
|         final id = args['id']; |         final id = args['id']; | ||||||
|         final indexOf = connectionIds.indexOf(id); |         final indexOf = connectionIds.indexOf(id); | ||||||
|         if (indexOf >= 0) { |         if (indexOf >= 0) { | ||||||
|           initialIndex.value = indexOf; |           initialIndex = indexOf; | ||||||
|  |           tabController.value.animateTo(initialIndex, duration: Duration.zero); | ||||||
|         } else { |         } else { | ||||||
|           connectionIds.add(id); |           connectionIds.add(id); | ||||||
|           initialIndex.value = connectionIds.length - 1; |           initialIndex = connectionIds.length - 1; | ||||||
|  |           tabController.value = TabController( | ||||||
|  |               length: connectionIds.length, | ||||||
|  |               initialIndex: initialIndex, | ||||||
|  |               vsync: this); | ||||||
|         } |         } | ||||||
|       } else if (call.method == "onDestroy") { |       } else if (call.method == "onDestroy") { | ||||||
|         print("executing onDestroy hook, closing ${connectionIds}"); |         print("executing onDestroy hook, closing ${connectionIds}"); | ||||||
| @ -65,54 +73,53 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> | |||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     return Scaffold( |     return Scaffold( | ||||||
|       body: Obx( |       body: Column( | ||||||
|         ()=> DefaultTabController( |         children: [ | ||||||
|           initialIndex: initialIndex.value, |           DesktopTitleBar( | ||||||
|           length: connectionIds.length, |             child: Obx( | ||||||
|           animationDuration: Duration.zero, |               () => TabBar( | ||||||
|           child: Column( |                   controller: tabController.value, | ||||||
|             children: [ |                   isScrollable: true, | ||||||
|               DesktopTitleBar( |                   labelColor: Colors.white, | ||||||
|                 child: TabBar( |                   physics: NeverScrollableScrollPhysics(), | ||||||
|                     isScrollable: true, |                   indicatorColor: Colors.white, | ||||||
|                     labelColor: Colors.white, |                   tabs: connectionIds | ||||||
|                     physics: NeverScrollableScrollPhysics(), |                       .map((e) => Tab( | ||||||
|                     indicatorColor: Colors.white, |                             key: Key('T$e'), | ||||||
|                     tabs: connectionIds |                             child: Row( | ||||||
|                         .map((e) => Tab( |                               mainAxisSize: MainAxisSize.min, | ||||||
|                               child: Row( |                               crossAxisAlignment: CrossAxisAlignment.center, | ||||||
|                                 mainAxisSize: MainAxisSize.min, |                               children: [ | ||||||
|                                 crossAxisAlignment: CrossAxisAlignment.center, |                                 Text(e), | ||||||
|                                 children: [ |                                 SizedBox( | ||||||
|                                   Text(e), |                                   width: 4, | ||||||
|                                   SizedBox( |                                 ), | ||||||
|                                     width: 4, |                                 InkWell( | ||||||
|                                   ), |                                     onTap: () { | ||||||
|                                   InkWell( |                                       onRemoveId(e); | ||||||
|                                       onTap: () { |                                     }, | ||||||
|                                         onRemoveId(e); |                                     child: Icon( | ||||||
|                                       }, |                                       Icons.highlight_remove, | ||||||
|                                       child: Icon( |                                       size: 20, | ||||||
|                                         Icons.highlight_remove, |                                     )) | ||||||
|                                         size: 20, |                               ], | ||||||
|                                       )) |                             ), | ||||||
|                                 ], |                           )) | ||||||
|                               ), |                       .toList()), | ||||||
|                             )) |             ), | ||||||
|                         .toList()), |  | ||||||
|               ), |  | ||||||
|               Expanded( |  | ||||||
|                 child: TabBarView( |  | ||||||
|                     children: connectionIds |  | ||||||
|                         .map((e) => Container( |  | ||||||
|                             child: FileManagerPage( |  | ||||||
|                                 key: ValueKey(e), |  | ||||||
|                                 id: e))) //RemotePage(key: ValueKey(e), id: e)) |  | ||||||
|                         .toList()), |  | ||||||
|               ) |  | ||||||
|             ], |  | ||||||
|           ), |           ), | ||||||
|         ), |           Expanded( | ||||||
|  |             child: Obx( | ||||||
|  |               () => TabBarView( | ||||||
|  |                   controller: tabController.value, | ||||||
|  |                   children: connectionIds | ||||||
|  |                       .map((e) => FileManagerPage( | ||||||
|  |                           key: ValueKey(e), | ||||||
|  |                           id: e)) //RemotePage(key: ValueKey(e), id: e)) | ||||||
|  |                       .toList()), | ||||||
|  |             ), | ||||||
|  |           ) | ||||||
|  |         ], | ||||||
|       ), |       ), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| @ -123,6 +130,8 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> | |||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     connectionIds.removeAt(indexOf); |     connectionIds.removeAt(indexOf); | ||||||
|     initialIndex.value = max(0, initialIndex.value - 1); |     initialIndex = max(0, initialIndex - 1); | ||||||
|  |     tabController.value = TabController( | ||||||
|  |         length: connectionIds.length, initialIndex: initialIndex, vsync: this); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -77,7 +77,7 @@ class _RemotePageState extends State<RemotePage> | |||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   void dispose() { |   void dispose() { | ||||||
|     print("remote page dispose"); |     print("REMOTE PAGE dispose ${widget.id}"); | ||||||
|     hideMobileActionsOverlay(); |     hideMobileActionsOverlay(); | ||||||
|     _ffi.listenToMouse(false); |     _ffi.listenToMouse(false); | ||||||
|     _ffi.invokeMethod("enable_soft_keyboard", true); |     _ffi.invokeMethod("enable_soft_keyboard", true); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user