feat(client): 移动端横滑手势——tab 根左右滑切 tab、二级屏左滑退出

- tab 根(库存/入库/出库/财务/我的):左滑下一个 tab、右滑上一个(不循环)
- 二级屏:左滑返回(同顶栏返回箭头语义),右滑无响应
- 仅窄屏生效;内容区横向滚动(分段 tab/表格横滚)在手势竞技场优先,不冲突

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-04 20:31:33 +08:00
parent 980e38e020
commit 9efd1177b7
+24 -1
View File
@@ -224,6 +224,29 @@ class _AppShellState extends ConsumerState<AppShell> {
// 并在顶栏出返回箭头(_buildTopBar 内)。
final isTabRoot = _tabRoots.contains(widget.location);
// 窄屏横滑手势(2026-07-04 拍板):tab 根左右滑切换相邻 tab(不循环);
// 二级屏左滑退出(回来源/我的),右滑无响应。内容区里的横向滚动
//(分段 tab / 表格横滚)在手势竞技场中优先,互不冲突。
Widget shellContent = widget.navigationShell;
if (isMobile) {
shellContent = GestureDetector(
behavior: HitTestBehavior.translucent,
onHorizontalDragEnd: (d) {
final v = d.primaryVelocity ?? 0;
if (v.abs() < 200) return; // 轻微拖动不触发
if (isTabRoot) {
final pos = _tabForBranch(widget.navigationShell.currentIndex);
final next = v < 0 ? pos + 1 : pos - 1; // 左滑→下一个 tab
if (next < 0 || next >= _mobileTabs.length) return;
_goBranch(_mobileTabs[next].$3);
} else if (v < 0) {
_backFromSecondary(); // 左滑退出;右滑无响应
}
},
child: widget.navigationShell,
);
}
final Widget shell = SelectionArea(
child: Scaffold(
body: Column(
@@ -238,7 +261,7 @@ class _AppShellState extends ConsumerState<AppShell> {
children: [
..._buildBanners(context, isOnline, updateInfo,
updateNotifier, licenseInfo),
Expanded(child: widget.navigationShell),
Expanded(child: shellContent),
if (!isMobile) AppStatusBar(loginTime: _loginTime),
],
),