mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-05 02:24:52 +08:00
more fab anim
Closes #2265 Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
@@ -22,7 +22,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
abstract class CommonDynPageState<T extends StatefulWidget> extends State<T>
|
abstract class CommonDynPageState<T extends StatefulWidget> extends State<T>
|
||||||
with SingleTickerProviderStateMixin, FabMixin {
|
with SingleTickerProviderStateMixin, BaseFabMixin, FabMixin {
|
||||||
CommonDynController get controller;
|
CommonDynController get controller;
|
||||||
|
|
||||||
late final ScrollController scrollController;
|
late final ScrollController scrollController;
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
mixin FabMixin<T extends StatefulWidget> on State<T>, TickerProvider {
|
mixin BaseFabMixin<T extends StatefulWidget> on State<T>, TickerProvider {
|
||||||
bool _isFabVisible = true;
|
late bool _isFabVisible = true;
|
||||||
late final AnimationController _fabAnimationCtr;
|
AnimationController get fabAnimationCtr;
|
||||||
late final Animation<Offset> fabAnimation;
|
Animation<Offset> get fabAnimation;
|
||||||
|
|
||||||
@override
|
AnimationController _initController() {
|
||||||
void initState() {
|
return AnimationController(
|
||||||
super.initState();
|
|
||||||
_fabAnimationCtr = AnimationController(
|
|
||||||
vsync: this,
|
vsync: this,
|
||||||
duration: const Duration(milliseconds: 100),
|
duration: const Duration(milliseconds: 100),
|
||||||
);
|
);
|
||||||
fabAnimation = _fabAnimationCtr.drive(
|
}
|
||||||
|
|
||||||
|
Animation<Offset> _initAnimation() {
|
||||||
|
return fabAnimationCtr.drive(
|
||||||
Tween<Offset>(
|
Tween<Offset>(
|
||||||
begin: Offset.zero,
|
begin: Offset.zero,
|
||||||
end: const Offset(0.0, 1.0),
|
end: const Offset(0.0, 1.0),
|
||||||
@@ -23,20 +24,51 @@ mixin FabMixin<T extends StatefulWidget> on State<T>, TickerProvider {
|
|||||||
void showFab() {
|
void showFab() {
|
||||||
if (!_isFabVisible) {
|
if (!_isFabVisible) {
|
||||||
_isFabVisible = true;
|
_isFabVisible = true;
|
||||||
_fabAnimationCtr.reverse();
|
fabAnimationCtr.reverse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hideFab() {
|
void hideFab() {
|
||||||
if (_isFabVisible) {
|
if (_isFabVisible) {
|
||||||
_isFabVisible = false;
|
_isFabVisible = false;
|
||||||
_fabAnimationCtr.forward();
|
fabAnimationCtr.forward();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin FabMixin<T extends StatefulWidget> on BaseFabMixin<T> {
|
||||||
|
@override
|
||||||
|
late final AnimationController fabAnimationCtr;
|
||||||
|
@override
|
||||||
|
late final Animation<Offset> fabAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
fabAnimationCtr = _initController();
|
||||||
|
fabAnimation = _initAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_fabAnimationCtr.dispose();
|
fabAnimationCtr.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin LazyFabMixin<T extends StatefulWidget> on BaseFabMixin<T> {
|
||||||
|
AnimationController? _fabAnimationCtr;
|
||||||
|
Animation<Offset>? _fabAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
AnimationController get fabAnimationCtr =>
|
||||||
|
_fabAnimationCtr ??= _initController();
|
||||||
|
@override
|
||||||
|
Animation<Offset> get fabAnimation => _fabAnimation ??= _initAnimation();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_fabAnimationCtr?.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'package:PiliPlus/http/loading_state.dart';
|
|||||||
import 'package:PiliPlus/models/common/image_type.dart';
|
import 'package:PiliPlus/models/common/image_type.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_feed/item.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_feed/item.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/top_details.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/top_details.dart';
|
||||||
|
import 'package:PiliPlus/pages/common/fab_mixin.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics/widgets/dynamic_panel.dart';
|
import 'package:PiliPlus/pages/dynamics/widgets/dynamic_panel.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics_create/view.dart';
|
import 'package:PiliPlus/pages/dynamics_create/view.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics_topic/controller.dart';
|
import 'package:PiliPlus/pages/dynamics_topic/controller.dart';
|
||||||
@@ -38,7 +39,8 @@ class DynTopicPage extends StatefulWidget {
|
|||||||
State<DynTopicPage> createState() => _DynTopicPageState();
|
State<DynTopicPage> createState() => _DynTopicPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DynTopicPageState extends State<DynTopicPage> with DynMixin {
|
class _DynTopicPageState extends State<DynTopicPage>
|
||||||
|
with DynMixin, SingleTickerProviderStateMixin, BaseFabMixin, FabMixin {
|
||||||
final DynTopicController _controller = Get.put(
|
final DynTopicController _controller = Get.put(
|
||||||
DynTopicController(),
|
DynTopicController(),
|
||||||
tag: Utils.generateRandomString(8),
|
tag: Utils.generateRandomString(8),
|
||||||
@@ -48,27 +50,22 @@ class _DynTopicPageState extends State<DynTopicPage> with DynMixin {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final colorScheme = ColorScheme.of(context);
|
final colorScheme = ColorScheme.of(context);
|
||||||
final padding = MediaQuery.viewPaddingOf(context);
|
final padding = MediaQuery.viewPaddingOf(context);
|
||||||
return Scaffold(
|
return Material(
|
||||||
resizeToAvoidBottomInset: false,
|
child: Stack(
|
||||||
floatingActionButton: FloatingActionButton.extended(
|
clipBehavior: .none,
|
||||||
onPressed: () {
|
children: [
|
||||||
if (_controller.isLogin) {
|
refreshIndicator(
|
||||||
CreateDynPanel.onCreateDyn(
|
|
||||||
context,
|
|
||||||
topic: Pair(
|
|
||||||
first: int.parse(_controller.topicId),
|
|
||||||
second: _controller.topicName,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
SmartDialog.showToast('账号未登录');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
icon: const Icon(CustomIcons.topic_tag, size: 20),
|
|
||||||
label: const Text('参与话题'),
|
|
||||||
),
|
|
||||||
body: refreshIndicator(
|
|
||||||
onRefresh: _controller.onRefresh,
|
onRefresh: _controller.onRefresh,
|
||||||
|
child: NotificationListener<UserScrollNotification>(
|
||||||
|
onNotification: (notification) {
|
||||||
|
final direction = notification.direction;
|
||||||
|
if (direction == .forward) {
|
||||||
|
showFab();
|
||||||
|
} else if (direction == .reverse) {
|
||||||
|
hideFab();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
controller: _controller.scrollController,
|
controller: _controller.scrollController,
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
@@ -81,7 +78,8 @@ class _DynTopicPageState extends State<DynTopicPage> with DynMixin {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Obx(() {
|
Obx(() {
|
||||||
final allSortBy = _controller.topicSortByConf.value?.allSortBy;
|
final allSortBy =
|
||||||
|
_controller.topicSortByConf.value?.allSortBy;
|
||||||
if (allSortBy != null && allSortBy.isNotEmpty) {
|
if (allSortBy != null && allSortBy.isNotEmpty) {
|
||||||
return SliverPinnedHeader(
|
return SliverPinnedHeader(
|
||||||
backgroundColor: colorScheme.surface,
|
backgroundColor: colorScheme.surface,
|
||||||
@@ -145,6 +143,38 @@ class _DynTopicPageState extends State<DynTopicPage> with DynMixin {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
right: padding.right + kFloatingActionButtonMargin,
|
||||||
|
bottom: 0,
|
||||||
|
child: SlideTransition(
|
||||||
|
position: fabAnimation,
|
||||||
|
child: Padding(
|
||||||
|
padding: .only(
|
||||||
|
bottom: padding.bottom + kFloatingActionButtonMargin,
|
||||||
|
),
|
||||||
|
child: FloatingActionButton.extended(
|
||||||
|
onPressed: () {
|
||||||
|
if (_controller.isLogin) {
|
||||||
|
CreateDynPanel.onCreateDyn(
|
||||||
|
context,
|
||||||
|
topic: Pair(
|
||||||
|
first: int.parse(_controller.topicId),
|
||||||
|
second: _controller.topicName,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
SmartDialog.showToast('账号未登录');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: const Icon(CustomIcons.topic_tag, size: 20),
|
||||||
|
label: const Text('参与话题'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
|||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/common/follow_order_type.dart';
|
import 'package:PiliPlus/models/common/follow_order_type.dart';
|
||||||
import 'package:PiliPlus/models_new/follow/list.dart';
|
import 'package:PiliPlus/models_new/follow/list.dart';
|
||||||
|
import 'package:PiliPlus/pages/common/fab_mixin.dart';
|
||||||
import 'package:PiliPlus/pages/follow/child/child_controller.dart';
|
import 'package:PiliPlus/pages/follow/child/child_controller.dart';
|
||||||
import 'package:PiliPlus/pages/follow/controller.dart';
|
import 'package:PiliPlus/pages/follow/controller.dart';
|
||||||
import 'package:PiliPlus/pages/follow/widgets/follow_item.dart';
|
import 'package:PiliPlus/pages/follow/widgets/follow_item.dart';
|
||||||
@@ -37,7 +38,11 @@ class FollowChildPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _FollowChildPageState extends State<FollowChildPage>
|
class _FollowChildPageState extends State<FollowChildPage>
|
||||||
with AutomaticKeepAliveClientMixin {
|
with
|
||||||
|
AutomaticKeepAliveClientMixin,
|
||||||
|
SingleTickerProviderStateMixin,
|
||||||
|
BaseFabMixin,
|
||||||
|
LazyFabMixin {
|
||||||
late String _tag;
|
late String _tag;
|
||||||
late FollowChildController _followController;
|
late FollowChildController _followController;
|
||||||
|
|
||||||
@@ -107,10 +112,27 @@ class _FollowChildPageState extends State<FollowChildPage>
|
|||||||
return Stack(
|
return Stack(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
child,
|
NotificationListener<UserScrollNotification>(
|
||||||
|
onNotification: (notification) {
|
||||||
|
final direction = notification.direction;
|
||||||
|
if (direction == .forward) {
|
||||||
|
showFab();
|
||||||
|
} else if (direction == .reverse) {
|
||||||
|
hideFab();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
right: kFloatingActionButtonMargin + padding.right,
|
right: kFloatingActionButtonMargin + padding.right,
|
||||||
|
bottom: 0,
|
||||||
|
child: SlideTransition(
|
||||||
|
position: fabAnimation,
|
||||||
|
child: Padding(
|
||||||
|
padding: .only(
|
||||||
bottom: kFloatingActionButtonMargin + padding.bottom,
|
bottom: kFloatingActionButtonMargin + padding.bottom,
|
||||||
|
),
|
||||||
child: FloatingActionButton.extended(
|
child: FloatingActionButton.extended(
|
||||||
onPressed: () => _followController
|
onPressed: () => _followController
|
||||||
..setOrderType(
|
..setOrderType(
|
||||||
@@ -120,7 +142,11 @@ class _FollowChildPageState extends State<FollowChildPage>
|
|||||||
)
|
)
|
||||||
..onReload(),
|
..onReload(),
|
||||||
icon: const Icon(Icons.format_list_bulleted, size: 20),
|
icon: const Icon(Icons.format_list_bulleted, size: 20),
|
||||||
label: Obx(() => Text(_followController.orderType.value.title)),
|
label: Obx(
|
||||||
|
() => Text(_followController.orderType.value.title),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class MainReplyPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MainReplyPageState extends State<MainReplyPage>
|
class _MainReplyPageState extends State<MainReplyPage>
|
||||||
with SingleTickerProviderStateMixin, FabMixin {
|
with SingleTickerProviderStateMixin, BaseFabMixin, FabMixin {
|
||||||
final _controller = Get.put(
|
final _controller = Get.put(
|
||||||
MainReplyController(),
|
MainReplyController(),
|
||||||
tag: Utils.generateRandomString(8),
|
tag: Utils.generateRandomString(8),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
|||||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models_new/space/space_opus/item.dart';
|
import 'package:PiliPlus/models_new/space/space_opus/item.dart';
|
||||||
|
import 'package:PiliPlus/pages/common/fab_mixin.dart';
|
||||||
import 'package:PiliPlus/pages/member_opus/controller.dart';
|
import 'package:PiliPlus/pages/member_opus/controller.dart';
|
||||||
import 'package:PiliPlus/pages/member_opus/widgets/space_opus_item.dart';
|
import 'package:PiliPlus/pages/member_opus/widgets/space_opus_item.dart';
|
||||||
import 'package:PiliPlus/utils/grid.dart';
|
import 'package:PiliPlus/utils/grid.dart';
|
||||||
@@ -30,7 +31,11 @@ class MemberOpus extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MemberOpusState extends State<MemberOpus>
|
class _MemberOpusState extends State<MemberOpus>
|
||||||
with AutomaticKeepAliveClientMixin {
|
with
|
||||||
|
AutomaticKeepAliveClientMixin,
|
||||||
|
SingleTickerProviderStateMixin,
|
||||||
|
BaseFabMixin,
|
||||||
|
LazyFabMixin {
|
||||||
late final MemberOpusController _controller;
|
late final MemberOpusController _controller;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -50,9 +55,20 @@ class _MemberOpusState extends State<MemberOpus>
|
|||||||
super.build(context);
|
super.build(context);
|
||||||
final bottom = MediaQuery.viewPaddingOf(context).bottom;
|
final bottom = MediaQuery.viewPaddingOf(context).bottom;
|
||||||
return Stack(
|
return Stack(
|
||||||
|
clipBehavior: .none,
|
||||||
children: [
|
children: [
|
||||||
refreshIndicator(
|
refreshIndicator(
|
||||||
onRefresh: _controller.onRefresh,
|
onRefresh: _controller.onRefresh,
|
||||||
|
child: NotificationListener<UserScrollNotification>(
|
||||||
|
onNotification: (notification) {
|
||||||
|
final direction = notification.direction;
|
||||||
|
if (direction == .forward) {
|
||||||
|
showFab();
|
||||||
|
} else if (direction == .reverse) {
|
||||||
|
hideFab();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
slivers: [
|
slivers: [
|
||||||
@@ -68,10 +84,17 @@ class _MemberOpusState extends State<MemberOpus>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
if (_controller.filter?.isNotEmpty == true)
|
if (_controller.filter?.isNotEmpty == true)
|
||||||
Positioned(
|
Positioned(
|
||||||
right: kFloatingActionButtonMargin,
|
right: kFloatingActionButtonMargin,
|
||||||
|
bottom: 0,
|
||||||
|
child: SlideTransition(
|
||||||
|
position: fabAnimation,
|
||||||
|
child: Padding(
|
||||||
|
padding: .only(
|
||||||
bottom: bottom + kFloatingActionButtonMargin,
|
bottom: bottom + kFloatingActionButtonMargin,
|
||||||
|
),
|
||||||
child: FloatingActionButton.extended(
|
child: FloatingActionButton.extended(
|
||||||
onPressed: () => showDialog(
|
onPressed: () => showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -117,6 +140,8 @@ class _MemberOpusState extends State<MemberOpus>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/sliver/sliver_floating_header.dart';
|
|||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/common/member/contribute_type.dart';
|
import 'package:PiliPlus/models/common/member/contribute_type.dart';
|
||||||
import 'package:PiliPlus/models_new/space/space_archive/item.dart';
|
import 'package:PiliPlus/models_new/space/space_archive/item.dart';
|
||||||
|
import 'package:PiliPlus/pages/common/fab_mixin.dart';
|
||||||
import 'package:PiliPlus/pages/member/controller.dart';
|
import 'package:PiliPlus/pages/member/controller.dart';
|
||||||
import 'package:PiliPlus/pages/member_video/controller.dart';
|
import 'package:PiliPlus/pages/member_video/controller.dart';
|
||||||
import 'package:PiliPlus/pages/member_video/widgets/video_card_h_member_video.dart';
|
import 'package:PiliPlus/pages/member_video/widgets/video_card_h_member_video.dart';
|
||||||
@@ -41,7 +42,12 @@ class MemberVideo extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MemberVideoState extends State<MemberVideo>
|
class _MemberVideoState extends State<MemberVideo>
|
||||||
with AutomaticKeepAliveClientMixin, GridMixin {
|
with
|
||||||
|
AutomaticKeepAliveClientMixin,
|
||||||
|
GridMixin,
|
||||||
|
SingleTickerProviderStateMixin,
|
||||||
|
BaseFabMixin,
|
||||||
|
LazyFabMixin {
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
|
|
||||||
@@ -121,19 +127,38 @@ class _MemberVideoState extends State<MemberVideo>
|
|||||||
return Stack(
|
return Stack(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
child,
|
NotificationListener<UserScrollNotification>(
|
||||||
|
onNotification: (notification) {
|
||||||
|
final direction = notification.direction;
|
||||||
|
if (direction == .forward) {
|
||||||
|
showFab();
|
||||||
|
} else if (direction == .reverse) {
|
||||||
|
hideFab();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
Obx(
|
Obx(
|
||||||
() => !_controller.isLocating.value
|
() => !_controller.isLocating.value
|
||||||
? Positioned(
|
? Positioned(
|
||||||
right: kFloatingActionButtonMargin,
|
right: kFloatingActionButtonMargin,
|
||||||
bottom: kFloatingActionButtonMargin + padding.bottom,
|
bottom: 0,
|
||||||
|
child: SlideTransition(
|
||||||
|
position: fabAnimation,
|
||||||
|
child: Padding(
|
||||||
|
padding: .only(
|
||||||
|
bottom: padding.bottom + kFloatingActionButtonMargin,
|
||||||
|
),
|
||||||
child: FloatingActionButton.extended(
|
child: FloatingActionButton.extended(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final fromViewAid = _controller.fromViewAid;
|
final fromViewAid = _controller.fromViewAid;
|
||||||
_controller.isLocating.value = true;
|
_controller.isLocating.value = true;
|
||||||
final locatedIndex =
|
final locatedIndex =
|
||||||
_controller.loadingState.value.dataOrNull
|
_controller.loadingState.value.dataOrNull
|
||||||
?.indexWhere((i) => i.param == fromViewAid) ??
|
?.indexWhere(
|
||||||
|
(i) => i.param == fromViewAid,
|
||||||
|
) ??
|
||||||
-1;
|
-1;
|
||||||
if (locatedIndex == -1) {
|
if (locatedIndex == -1) {
|
||||||
_controller
|
_controller
|
||||||
@@ -148,6 +173,8 @@ class _MemberVideoState extends State<MemberVideo>
|
|||||||
},
|
},
|
||||||
label: const Text('定位至上次观看'),
|
label: const Text('定位至上次观看'),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ abstract class BaseVideoWebState<
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const .fromLTRB(14, 0, 8, 4),
|
padding: const .fromLTRB(14, 0, 8, 4),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
|
clipBehavior: .none,
|
||||||
alignment: .centerLeft,
|
alignment: .centerLeft,
|
||||||
children: [
|
children: [
|
||||||
?buildCount(),
|
?buildCount(),
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
|||||||
with
|
with
|
||||||
AutomaticKeepAliveClientMixin,
|
AutomaticKeepAliveClientMixin,
|
||||||
SingleTickerProviderStateMixin,
|
SingleTickerProviderStateMixin,
|
||||||
|
BaseFabMixin,
|
||||||
FabMixin {
|
FabMixin {
|
||||||
late VideoReplyController _videoReplyController;
|
late VideoReplyController _videoReplyController;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user