mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-02 07:10:13 +08:00
@@ -1,5 +1,6 @@
|
||||
import 'dart:math' show max;
|
||||
|
||||
import 'package:PiliPlus/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:flutter/gestures.dart' show HorizontalDragGestureRecognizer;
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -12,8 +13,10 @@ abstract class CommonSlidePage extends StatefulWidget {
|
||||
}
|
||||
|
||||
mixin CommonSlideMixin<T extends CommonSlidePage> on State<T>, TickerProvider {
|
||||
static const double offset = 30.0;
|
||||
double? _downDx;
|
||||
late double _maxWidth;
|
||||
double get maxWidth => _maxWidth;
|
||||
late bool _isRTL = false;
|
||||
late final bool enableSlide;
|
||||
late final AnimationController _animController;
|
||||
@@ -33,7 +36,6 @@ mixin CommonSlideMixin<T extends CommonSlidePage> on State<T>, TickerProvider {
|
||||
_slideDragGestureRecognizer =
|
||||
SlideDragGestureRecognizer(
|
||||
isDxAllowed: (double dx) {
|
||||
const offset = 30;
|
||||
final isLTR = dx <= offset;
|
||||
final isRTL = dx >= _maxWidth - offset;
|
||||
if (isLTR || isRTL) {
|
||||
@@ -111,6 +113,8 @@ mixin CommonSlideMixin<T extends CommonSlidePage> on State<T>, TickerProvider {
|
||||
);
|
||||
}
|
||||
|
||||
typedef IsDxAllowed = bool Function(double dx);
|
||||
|
||||
class SlideDragGestureRecognizer extends HorizontalDragGestureRecognizer {
|
||||
SlideDragGestureRecognizer({
|
||||
super.debugOwner,
|
||||
@@ -119,7 +123,24 @@ class SlideDragGestureRecognizer extends HorizontalDragGestureRecognizer {
|
||||
required this.isDxAllowed,
|
||||
});
|
||||
|
||||
final bool Function(double dx) isDxAllowed;
|
||||
final IsDxAllowed isDxAllowed;
|
||||
|
||||
@override
|
||||
bool isPointerAllowed(PointerEvent event) {
|
||||
return isDxAllowed(event.localPosition.dx) && super.isPointerAllowed(event);
|
||||
}
|
||||
}
|
||||
|
||||
class TabBarDragGestureRecognizer
|
||||
extends CustomHorizontalDragGestureRecognizer {
|
||||
TabBarDragGestureRecognizer({
|
||||
super.debugOwner,
|
||||
super.supportedDevices,
|
||||
super.allowedButtonsFilter,
|
||||
required this.isDxAllowed,
|
||||
});
|
||||
|
||||
final IsDxAllowed isDxAllowed;
|
||||
|
||||
@override
|
||||
bool isPointerAllowed(PointerEvent event) {
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'package:PiliPlus/common/widgets/flutter/page/tabs.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/image_save.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
import 'package:PiliPlus/common/widgets/stat/stat.dart';
|
||||
import 'package:PiliPlus/http/fav.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
@@ -205,30 +204,42 @@ class _EpisodePanelState extends State<EpisodePanel>
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
late final _isMulti =
|
||||
widget.type == EpisodeType.season && widget.list.length > 1;
|
||||
|
||||
@override
|
||||
Widget buildPage(ThemeData theme) {
|
||||
final isMulti = widget.type == EpisodeType.season && widget.list.length > 1;
|
||||
|
||||
Widget tabBar() => TabBar(
|
||||
controller: _tabController,
|
||||
padding: const EdgeInsets.only(right: 60),
|
||||
isScrollable: true,
|
||||
tabs: widget.list.map((item) => Tab(text: item.title)).toList(),
|
||||
dividerHeight: 1,
|
||||
dividerColor: theme.dividerColor.withValues(alpha: 0.1),
|
||||
return Material(
|
||||
color: showTitle ? theme.colorScheme.surface : null,
|
||||
type: showTitle ? MaterialType.canvas : MaterialType.transparency,
|
||||
child: Column(
|
||||
children: [
|
||||
_buildToolbar(theme),
|
||||
if (_isMulti)
|
||||
TabBar(
|
||||
controller: _tabController,
|
||||
padding: const EdgeInsets.only(right: 60),
|
||||
isScrollable: true,
|
||||
tabs: widget.list.map((item) => Tab(text: item.title)).toList(),
|
||||
dividerHeight: 1,
|
||||
dividerColor: theme.dividerColor.withValues(alpha: 0.1),
|
||||
),
|
||||
Expanded(child: enableSlide ? slideList(theme) : buildList(theme)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (isMulti && enableSlide) {
|
||||
return CustomTabBarView(
|
||||
@override
|
||||
Widget buildList(ThemeData theme) {
|
||||
if (_isMulti) {
|
||||
return TabBarView<TabBarDragGestureRecognizer>(
|
||||
controller: _tabController,
|
||||
physics: const CustomTabBarViewScrollPhysics(),
|
||||
bgColor: theme.colorScheme.surface,
|
||||
header: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildToolbar(theme),
|
||||
tabBar(),
|
||||
],
|
||||
horizontalDragGestureRecognizer: TabBarDragGestureRecognizer(
|
||||
isDxAllowed: (double dx) => enableSlide
|
||||
? dx > CommonSlideMixin.offset &&
|
||||
dx < maxWidth - CommonSlideMixin.offset
|
||||
: true,
|
||||
),
|
||||
children: List.generate(
|
||||
widget.list.length,
|
||||
@@ -240,37 +251,6 @@ class _EpisodePanelState extends State<EpisodePanel>
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Material(
|
||||
color: showTitle ? theme.colorScheme.surface : null,
|
||||
type: showTitle ? MaterialType.canvas : MaterialType.transparency,
|
||||
child: Column(
|
||||
children: [
|
||||
_buildToolbar(theme),
|
||||
if (isMulti) ...[
|
||||
tabBar(),
|
||||
Expanded(
|
||||
child: tabBarView(
|
||||
controller: _tabController,
|
||||
children: List.generate(
|
||||
widget.list.length,
|
||||
(index) => _buildBody(
|
||||
theme,
|
||||
index,
|
||||
widget.list[index].episodes,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
] else
|
||||
Expanded(child: enableSlide ? slideList(theme) : buildList(theme)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildList(ThemeData theme) {
|
||||
return _buildBody(theme, 0, _getCurrEpisodes);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'package:PiliPlus/common/widgets/appbar/appbar.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/page/tabs.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart';
|
||||
import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
@@ -10,7 +12,7 @@ import 'package:PiliPlus/pages/history/controller.dart';
|
||||
import 'package:PiliPlus/pages/history/widgets/item.dart';
|
||||
import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart';
|
||||
import 'package:PiliPlus/utils/grid.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart' hide TabBarView;
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class HistoryPage extends StatefulWidget {
|
||||
@@ -130,6 +132,8 @@ class _HistoryPageState extends State<HistoryPage>
|
||||
? const NeverScrollableScrollPhysics()
|
||||
: const CustomTabBarViewScrollPhysics(),
|
||||
controller: _historyController.tabController,
|
||||
horizontalDragGestureRecognizer:
|
||||
CustomHorizontalDragGestureRecognizer(),
|
||||
children: [
|
||||
KeepAliveWrapper(builder: (context) => child),
|
||||
..._historyController.tabs.map(
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:PiliPlus/common/widgets/appbar/appbar.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/page/tabs.dart';
|
||||
import 'package:PiliPlus/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
|
||||
import 'package:PiliPlus/models/common/later_view_type.dart';
|
||||
@@ -11,7 +13,7 @@ import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/extension/get_ext.dart';
|
||||
import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart';
|
||||
import 'package:PiliPlus/utils/request_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart' hide TabBarView;
|
||||
import 'package:get/get.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
@@ -137,6 +139,8 @@ class _LaterPageState extends State<LaterPage>
|
||||
? const NeverScrollableScrollPhysics()
|
||||
: const CustomTabBarViewScrollPhysics(),
|
||||
controller: _tabController,
|
||||
horizontalDragGestureRecognizer:
|
||||
CustomHorizontalDragGestureRecognizer(),
|
||||
children: LaterViewType.values
|
||||
.map((item) => item.page)
|
||||
.toList(),
|
||||
|
||||
@@ -5,7 +5,9 @@ import 'dart:ui';
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_icon.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/page/page_view.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/text_field/controller.dart';
|
||||
import 'package:PiliPlus/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
@@ -41,7 +43,7 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:canvas_danmaku/canvas_danmaku.dart';
|
||||
import 'package:floating/floating.dart';
|
||||
import 'package:flutter/foundation.dart' show kDebugMode;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart' hide PageView;
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:screen_brightness_platform_interface/screen_brightness_platform_interface.dart';
|
||||
@@ -721,7 +723,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: 12, top: isPortrait ? 12 : 0),
|
||||
child: _liveRoomController.showSuperChat
|
||||
? PageView(
|
||||
? PageView<CustomHorizontalDragGestureRecognizer>(
|
||||
key: pageKey,
|
||||
controller: _liveRoomController.pageController,
|
||||
physics: const CustomTabBarViewScrollPhysics(
|
||||
@@ -729,6 +731,8 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
),
|
||||
onPageChanged: (value) =>
|
||||
_liveRoomController.pageIndex.value = value,
|
||||
horizontalDragGestureRecognizer:
|
||||
CustomHorizontalDragGestureRecognizer(),
|
||||
children: [
|
||||
KeepAliveWrapper(builder: (context) => chat()),
|
||||
SuperChatPanel(
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/page/page_view.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/pop_scope.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/tabs.dart';
|
||||
import 'package:PiliPlus/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/models/common/nav_bar_config.dart';
|
||||
import 'package:PiliPlus/pages/home/view.dart';
|
||||
@@ -18,7 +20,7 @@ import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/storage_key.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart' hide PageView;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tray_manager/tray_manager.dart';
|
||||
@@ -393,9 +395,11 @@ class _MainAppState extends PopScopeState<MainApp>
|
||||
children: _mainController.navigationBars.map((i) => i.page).toList(),
|
||||
);
|
||||
} else {
|
||||
child = PageView(
|
||||
child = PageView<CustomHorizontalDragGestureRecognizer>(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
controller: _mainController.controller,
|
||||
horizontalDragGestureRecognizer:
|
||||
CustomHorizontalDragGestureRecognizer(),
|
||||
children: _mainController.navigationBars.map((i) => i.page).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ import 'dart:math' show pi, max;
|
||||
|
||||
import 'package:PiliPlus/common/widgets/custom_icon.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart'
|
||||
show touchSlopH;
|
||||
import 'package:PiliPlus/common/widgets/image/custom_grid_view.dart'
|
||||
show CustomGridView, ImageModel;
|
||||
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
|
||||
@@ -187,11 +189,9 @@ List<SettingsModel> get extraSettings => [
|
||||
leading: const Icon(Icons.notifications_none),
|
||||
setKey: SettingBoxKey.checkDynamic,
|
||||
defaultVal: true,
|
||||
onChanged: (value) {
|
||||
Get.find<MainController>().checkDynamic = value;
|
||||
},
|
||||
onChanged: (value) => Get.find<MainController>().checkDynamic = value,
|
||||
onTap: (context) {
|
||||
int dynamicPeriod = Pref.dynamicPeriod;
|
||||
String dynamicPeriod = Pref.dynamicPeriod.toString();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
@@ -199,11 +199,9 @@ List<SettingsModel> get extraSettings => [
|
||||
title: const Text('检查周期'),
|
||||
content: TextFormField(
|
||||
autofocus: true,
|
||||
initialValue: dynamicPeriod.toString(),
|
||||
initialValue: dynamicPeriod,
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (value) {
|
||||
dynamicPeriod = int.tryParse(value) ?? 5;
|
||||
},
|
||||
onChanged: (value) => dynamicPeriod = value,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
decoration: const InputDecoration(suffixText: 'min'),
|
||||
),
|
||||
@@ -219,13 +217,14 @@ List<SettingsModel> get extraSettings => [
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
GStorage.setting.put(
|
||||
SettingBoxKey.dynamicPeriod,
|
||||
dynamicPeriod,
|
||||
);
|
||||
Get.find<MainController>().dynamicPeriod =
|
||||
dynamicPeriod * 60 * 1000;
|
||||
try {
|
||||
final val = int.parse(dynamicPeriod);
|
||||
Get.back();
|
||||
GStorage.setting.put(SettingBoxKey.dynamicPeriod, val);
|
||||
Get.find<MainController>().dynamicPeriod = val * 60 * 1000;
|
||||
} catch (e) {
|
||||
SmartDialog.showToast(e.toString());
|
||||
}
|
||||
},
|
||||
child: const Text('确定'),
|
||||
),
|
||||
@@ -312,9 +311,7 @@ List<SettingsModel> get extraSettings => [
|
||||
autofocus: true,
|
||||
initialValue: replyLengthLimit,
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (value) {
|
||||
replyLengthLimit = value;
|
||||
},
|
||||
onChanged: (value) => replyLengthLimit = value,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
decoration: const InputDecoration(suffixText: '行'),
|
||||
),
|
||||
@@ -365,12 +362,8 @@ List<SettingsModel> get extraSettings => [
|
||||
content: TextFormField(
|
||||
autofocus: true,
|
||||
initialValue: danmakuLineHeight,
|
||||
keyboardType: const TextInputType.numberWithOptions(
|
||||
decimal: true,
|
||||
),
|
||||
onChanged: (value) {
|
||||
danmakuLineHeight = value;
|
||||
},
|
||||
keyboardType: const .numberWithOptions(decimal: true),
|
||||
onChanged: (value) => danmakuLineHeight = value,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[\d\.]+')),
|
||||
],
|
||||
@@ -460,6 +453,56 @@ List<SettingsModel> get extraSettings => [
|
||||
setKey: SettingBoxKey.openInBrowser,
|
||||
defaultVal: false,
|
||||
),
|
||||
NormalModel(
|
||||
title: '横向滑动阈值',
|
||||
getSubtitle: () => '当前:「${Pref.touchSlopH}」',
|
||||
onTap: (context, setState) {
|
||||
String initialValue = Pref.touchSlopH.toString();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('横向滑动阈值'),
|
||||
content: TextFormField(
|
||||
autofocus: true,
|
||||
initialValue: initialValue,
|
||||
keyboardType: const .numberWithOptions(decimal: true),
|
||||
onChanged: (value) => initialValue = value,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[\d\.]+')),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
try {
|
||||
final val = double.parse(initialValue);
|
||||
Get.back();
|
||||
touchSlopH = val;
|
||||
await GStorage.setting.put(SettingBoxKey.touchSlopH, val);
|
||||
setState();
|
||||
} catch (e) {
|
||||
SmartDialog.showToast(e.toString());
|
||||
}
|
||||
},
|
||||
child: const Text('确定'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
leading: const Icon(Icons.pan_tool_alt_outlined),
|
||||
),
|
||||
NormalModel(
|
||||
title: '刷新滑动距离',
|
||||
leading: const Icon(Icons.refresh),
|
||||
@@ -687,9 +730,7 @@ List<SettingsModel> get extraSettings => [
|
||||
),
|
||||
setKey: SettingBoxKey.antiGoodsDyn,
|
||||
defaultVal: false,
|
||||
onChanged: (value) {
|
||||
DynamicsDataModel.antiGoodsDyn = value;
|
||||
},
|
||||
onChanged: (value) => DynamicsDataModel.antiGoodsDyn = value,
|
||||
),
|
||||
SwitchModel(
|
||||
title: '屏蔽带货评论',
|
||||
@@ -703,9 +744,7 @@ List<SettingsModel> get extraSettings => [
|
||||
),
|
||||
setKey: SettingBoxKey.antiGoodsReply,
|
||||
defaultVal: false,
|
||||
onChanged: (value) {
|
||||
ReplyGrpc.antiGoodsReply = value;
|
||||
},
|
||||
onChanged: (value) => ReplyGrpc.antiGoodsReply = value,
|
||||
),
|
||||
SwitchModel(
|
||||
title: '侧滑关闭二级页面',
|
||||
@@ -715,9 +754,7 @@ List<SettingsModel> get extraSettings => [
|
||||
),
|
||||
setKey: SettingBoxKey.slideDismissReplyPage,
|
||||
defaultVal: Platform.isIOS,
|
||||
onChanged: (value) {
|
||||
CommonSlideMixin.slideDismissReplyPage = value;
|
||||
},
|
||||
onChanged: (value) => CommonSlideMixin.slideDismissReplyPage = value,
|
||||
),
|
||||
const SwitchModel(
|
||||
title: '启用双指缩小视频',
|
||||
@@ -856,9 +893,7 @@ List<SettingsModel> get extraSettings => [
|
||||
leading: const Icon(Icons.search_outlined),
|
||||
setKey: SettingBoxKey.enableWordRe,
|
||||
defaultVal: false,
|
||||
onChanged: (value) {
|
||||
ReplyItemGrpc.enableWordRe = value;
|
||||
},
|
||||
onChanged: (value) => ReplyItemGrpc.enableWordRe = value,
|
||||
),
|
||||
const SwitchModel(
|
||||
title: '启用AI总结',
|
||||
|
||||
@@ -21,7 +21,7 @@ class PgcIntroPanel extends CommonSlidePage {
|
||||
const PgcIntroPanel({
|
||||
super.key,
|
||||
required this.item,
|
||||
super.enableSlide = false,
|
||||
super.enableSlide,
|
||||
this.videoTags,
|
||||
});
|
||||
|
||||
@@ -50,42 +50,61 @@ class _IntroDetailState extends State<PgcIntroPanel>
|
||||
|
||||
@override
|
||||
Widget buildPage(ThemeData theme) {
|
||||
return CustomTabBarView(
|
||||
controller: _tabController,
|
||||
physics: const CustomTabBarViewScrollPhysics(),
|
||||
bgColor: theme.colorScheme.surface,
|
||||
header: Row(
|
||||
return Material(
|
||||
color: theme.colorScheme.surface,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TabBar(
|
||||
controller: _tabController,
|
||||
dividerHeight: 0,
|
||||
isScrollable: true,
|
||||
tabAlignment: TabAlignment.start,
|
||||
dividerColor: Colors.transparent,
|
||||
tabs: const [
|
||||
Tab(text: '详情'),
|
||||
Tab(text: '点评'),
|
||||
],
|
||||
onTap: (index) {
|
||||
if (!_tabController.indexIsChanging) {
|
||||
if (index == 0) {
|
||||
_controller.animToTop();
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
tooltip: '关闭',
|
||||
icon: const Icon(Icons.close, size: 20),
|
||||
onPressed: Get.back,
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: TabBar(
|
||||
controller: _tabController,
|
||||
dividerHeight: 0,
|
||||
isScrollable: true,
|
||||
tabAlignment: TabAlignment.start,
|
||||
dividerColor: Colors.transparent,
|
||||
tabs: const [
|
||||
Tab(text: '详情'),
|
||||
Tab(text: '点评'),
|
||||
],
|
||||
onTap: (index) {
|
||||
if (!_tabController.indexIsChanging) {
|
||||
if (index == 0) {
|
||||
_controller.animToTop();
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
child: enableSlide ? slideList(theme) : buildList(theme),
|
||||
),
|
||||
IconButton(
|
||||
tooltip: '关闭',
|
||||
icon: const Icon(Icons.close, size: 20),
|
||||
onPressed: Get.back,
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildList(ThemeData theme) {
|
||||
return TabBarView<TabBarDragGestureRecognizer>(
|
||||
controller: _tabController,
|
||||
physics: const CustomTabBarViewScrollPhysics(),
|
||||
horizontalDragGestureRecognizer: TabBarDragGestureRecognizer(
|
||||
isDxAllowed: (double dx) => enableSlide
|
||||
? dx > CommonSlideMixin.offset &&
|
||||
dx < maxWidth - CommonSlideMixin.offset
|
||||
: true,
|
||||
),
|
||||
children: [
|
||||
KeepAliveWrapper(builder: (context) => buildList(theme)),
|
||||
KeepAliveWrapper(builder: (context) => _buildInfo(theme)),
|
||||
PgcReviewPage(
|
||||
name: widget.item.title!,
|
||||
mediaId: widget.item.mediaId,
|
||||
@@ -94,8 +113,7 @@ class _IntroDetailState extends State<PgcIntroPanel>
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildList(ThemeData theme) {
|
||||
Widget _buildInfo(ThemeData theme) {
|
||||
final TextStyle smallTitle = TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.colorScheme.onSurface,
|
||||
|
||||
Reference in New Issue
Block a user