feat: deliver RSchedule service login exams and elastic glass navigation
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Retains all tab states and scroll positions, with no page-swipe recognizer.
|
||||
class TabDeck extends StatefulWidget {
|
||||
const TabDeck({super.key, required this.index, required this.children});
|
||||
final int index;
|
||||
final List<Widget> children;
|
||||
@override
|
||||
State<TabDeck> createState() => _TabDeckState();
|
||||
}
|
||||
|
||||
class _TabDeckState extends State<TabDeck> with SingleTickerProviderStateMixin {
|
||||
late final AnimationController _motion = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 330),
|
||||
value: 1,
|
||||
);
|
||||
int? _outgoing;
|
||||
int _direction = 1;
|
||||
@override
|
||||
void didUpdateWidget(TabDeck oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.index != widget.index) {
|
||||
_outgoing = oldWidget.index;
|
||||
_direction = widget.index > oldWidget.index ? 1 : -1;
|
||||
if (MediaQuery.disableAnimationsOf(context)) {
|
||||
_motion.value = 1;
|
||||
} else {
|
||||
_motion.forward(from: 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_motion.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => AnimatedBuilder(
|
||||
animation: _motion,
|
||||
builder: (context, _) {
|
||||
final t = Curves.easeOutCubic.transform(_motion.value);
|
||||
return Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
for (var i = 0; i < widget.children.length; i++)
|
||||
Offstage(
|
||||
offstage:
|
||||
i != widget.index && (i != _outgoing || _motion.isCompleted),
|
||||
child: TickerMode(
|
||||
enabled: i == widget.index,
|
||||
child: IgnorePointer(
|
||||
ignoring: i != widget.index,
|
||||
child: ExcludeSemantics(
|
||||
excluding: i != widget.index,
|
||||
child: Opacity(
|
||||
opacity: i == widget.index
|
||||
? t
|
||||
: (i == _outgoing ? 1 - t : 0),
|
||||
child: Transform.translate(
|
||||
offset: Offset(
|
||||
(i == widget.index ? 1 - t : -t) * 22 * _direction,
|
||||
0,
|
||||
),
|
||||
child: widget.children[i],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user