Merge pull request #1412 from 21pages/tabbar

fix tabbar close button display problem when selected && hovered
This commit is contained in:
RustDesk 2022-08-31 20:03:09 +08:00 committed by GitHub
commit f91701910a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -484,7 +484,7 @@ class _ListView extends StatelessWidget {
} }
} }
class _Tab extends StatelessWidget { class _Tab extends StatefulWidget {
late final int index; late final int index;
late final Rx<String> label; late final Rx<String> label;
late final IconData? selectedIcon; late final IconData? selectedIcon;
@ -493,7 +493,6 @@ class _Tab extends StatelessWidget {
late final int selected; late final int selected;
late final Function() onClose; late final Function() onClose;
late final Function() onSelected; late final Function() onSelected;
final RxBool _hover = false.obs;
late final TarBarTheme theme; late final TarBarTheme theme;
final Widget Function(Widget icon, Widget label, TabThemeConf themeConf)? final Widget Function(Widget icon, Widget label, TabThemeConf themeConf)?
tabBuilder; tabBuilder;
@ -512,31 +511,39 @@ class _Tab extends StatelessWidget {
required this.theme}) required this.theme})
: super(key: key); : super(key: key);
@override
State<_Tab> createState() => _TabState();
}
class _TabState extends State<_Tab> with RestorationMixin {
final RestorableBool restoreHover = RestorableBool(false);
Widget _buildTabContent() { Widget _buildTabContent() {
bool showIcon = selectedIcon != null && unselectedIcon != null; bool showIcon =
bool isSelected = index == selected; widget.selectedIcon != null && widget.unselectedIcon != null;
bool isSelected = widget.index == widget.selected;
final icon = Offstage( final icon = Offstage(
offstage: !showIcon, offstage: !showIcon,
child: Icon( child: Icon(
isSelected ? selectedIcon : unselectedIcon, isSelected ? widget.selectedIcon : widget.unselectedIcon,
size: _kIconSize, size: _kIconSize,
color: isSelected color: isSelected
? theme.selectedtabIconColor ? widget.theme.selectedtabIconColor
: theme.unSelectedtabIconColor, : widget.theme.unSelectedtabIconColor,
).paddingOnly(right: 5)); ).paddingOnly(right: 5));
final labelWidget = Obx(() { final labelWidget = Obx(() {
return Text( return Text(
translate(label.value), translate(widget.label.value),
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: isSelected color: isSelected
? theme.selectedTextColor ? widget.theme.selectedTextColor
: theme.unSelectedTextColor), : widget.theme.unSelectedTextColor),
); );
}); });
if (tabBuilder == null) { if (widget.tabBuilder == null) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
@ -545,37 +552,38 @@ class _Tab extends StatelessWidget {
], ],
); );
} else { } else {
return tabBuilder!( return widget.tabBuilder!(icon, labelWidget,
icon, labelWidget, TabThemeConf(iconSize: _kIconSize, theme: theme)); TabThemeConf(iconSize: _kIconSize, theme: widget.theme));
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool showIcon = selectedIcon != null && unselectedIcon != null; bool isSelected = widget.index == widget.selected;
bool isSelected = index == selected; bool showDivider =
bool showDivider = index != selected - 1 && index != selected; widget.index != widget.selected - 1 && widget.index != widget.selected;
RxBool hover = restoreHover.value.obs;
return Ink( return Ink(
child: InkWell( child: InkWell(
onHover: (hover) => _hover.value = hover, onHover: (value) {
onTap: () => onSelected(), hover.value = value;
restoreHover.value = value;
},
onTap: () => widget.onSelected(),
child: Row( child: Row(
children: [ children: [
Container( SizedBox(
height: _kTabBarHeight, height: _kTabBarHeight,
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
_buildTabContent(), _buildTabContent(),
Offstage( Obx((() => _CloseButton(
offstage: !closable, visiable: hover.value && widget.closable,
child: Obx((() => _CloseButton( tabSelected: isSelected,
visiable: _hover.value, onClose: () => widget.onClose(),
tabSelected: isSelected, theme: widget.theme,
onClose: () => onClose(), )))
theme: theme,
))),
)
])).paddingSymmetric(horizontal: 10), ])).paddingSymmetric(horizontal: 10),
Offstage( Offstage(
offstage: !showDivider, offstage: !showDivider,
@ -583,7 +591,7 @@ class _Tab extends StatelessWidget {
width: 1, width: 1,
indent: _kDividerIndent, indent: _kDividerIndent,
endIndent: _kDividerIndent, endIndent: _kDividerIndent,
color: theme.dividerColor, color: widget.theme.dividerColor,
thickness: 1, thickness: 1,
), ),
) )
@ -592,6 +600,14 @@ class _Tab extends StatelessWidget {
), ),
); );
} }
@override
String? get restorationId => "_Tab${widget.label.value}";
@override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(restoreHover, 'restoreHover');
}
} }
class _CloseButton extends StatelessWidget { class _CloseButton extends StatelessWidget {
@ -615,7 +631,7 @@ class _CloseButton extends StatelessWidget {
child: Offstage( child: Offstage(
offstage: !visiable, offstage: !visiable,
child: InkWell( child: InkWell(
customBorder: RoundedRectangleBorder(), customBorder: const RoundedRectangleBorder(),
onTap: () => onClose(), onTap: () => onClose(),
child: Icon( child: Icon(
Icons.close, Icons.close,