Last active
March 31, 2022 09:46
-
-
Save vi-k/53ca5807a4fc3e99a1850abed38d938f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:math' as math; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter_bloc/flutter_bloc.dart'; | |
import 'package:my_theme/my_theme.dart'; | |
import 'package:physical/physical.dart'; | |
import 'package:physical_training/domain/interactor/physical/physical_interactor.dart'; | |
import 'package:physical_training/domain/repository/key_value_repository.dart'; | |
import 'package:physical_training/translations/translator.dart'; | |
import 'package:physical_training/ui/nodes/exercises/bloc/exercises_bloc/exercises_bloc.dart'; | |
class TabulaRasaScreen extends StatefulWidget { | |
const TabulaRasaScreen._({Key? key}) : super(key: key); | |
static Page page(BuildContext context) => | |
MaterialPage<void>(child: TabulaRasaScreen.screen(context)); | |
static Widget screen(BuildContext context) => BlocProvider( | |
create: (context) => ExercisesBloc( | |
physicalInteractor: context.read<PhysicalInteractor>(), | |
keyValueRepository: context.read<KeyValueRepository>(), | |
)..add(const ExercisesEvent.reload()), | |
// ..add(const ExercisesEvent.loadOrRestore()), | |
child: const TabulaRasaScreen._(), | |
); | |
@override | |
State<TabulaRasaScreen> createState() => _TabulaRasaScreenState(); | |
static _TabulaRasaScreenState of(BuildContext context) => | |
context.findAncestorStateOfType<_TabulaRasaScreenState>()!; | |
} | |
class _TabulaRasaScreenState extends State<TabulaRasaScreen> { | |
@override | |
Widget build(BuildContext context) => PhysicalScaffold( | |
body: Column( | |
children: [ | |
PhysicalTitleBar( | |
title: Text(context.tr.dev.tabulaRasa), | |
), | |
const _Content(), | |
], | |
), | |
); | |
} | |
class _Content extends StatefulWidget { | |
const _Content({Key? key}) : super(key: key); | |
@override | |
State<_Content> createState() => _ContentState(); | |
} | |
class _ContentState extends State<_Content> { | |
bool _opened = true; | |
@override | |
Widget build(BuildContext context) => Column( | |
children: [ | |
Center( | |
child: Row( | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
_Anima( | |
opened: _opened, | |
title: const Text('Заголовок'), | |
child: const Text( | |
'Описание Описание\nОписание Описание\nОписание Описание', | |
), | |
), | |
], | |
), | |
), | |
Center( | |
child: PhysicalButton.small( | |
label: const Text('open/close'), | |
onPressed: () { | |
setState(() { | |
_opened = !_opened; | |
}); | |
}, | |
), | |
), | |
], | |
); | |
} | |
class _Anima extends StatefulWidget { | |
const _Anima({ | |
Key? key, | |
required this.opened, | |
required this.title, | |
required this.child, | |
}) : super(key: key); | |
final Widget title; | |
final Widget child; | |
final bool opened; | |
@override | |
State<_Anima> createState() => __AnimaState(); | |
} | |
class __AnimaState extends State<_Anima> with SingleTickerProviderStateMixin { | |
late final AnimationController _animationController; | |
late final Animation<double> _animation; | |
late bool _opened; | |
bool get opened => _opened; | |
set opened(bool value) { | |
if (_opened != value) { | |
_opened = value; | |
if (_opened) { | |
_animationController.forward(); | |
} else { | |
_animationController.reverse(); | |
} | |
} | |
} | |
@override | |
void initState() { | |
super.initState(); | |
_opened = widget.opened; | |
_animationController = AnimationController( | |
vsync: this, | |
duration: CommonValues.defaultAnimationDuration * 2, | |
reverseDuration: CommonValues.defaultAnimationDuration * 4, | |
); | |
_animationController.value = _opened ? 1 : 0; | |
_animation = CurvedAnimation( | |
parent: _animationController, | |
curve: Curves.bounceOut, | |
reverseCurve: Curves.fastOutSlowIn.flipped, | |
); | |
} | |
@override | |
void didUpdateWidget(covariant _Anima oldWidget) { | |
super.didUpdateWidget(oldWidget); | |
opened = widget.opened; | |
} | |
@override | |
void dispose() { | |
_animationController.dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) => AnimatedBuilder( | |
animation: _animation, | |
builder: (context, child) => Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
PhysicalButton.small( | |
label: Row( | |
children: [ | |
widget.title, | |
const SizedBox(width: 10), | |
// Transform( | |
// alignment: FractionalOffset.center, | |
// transform: Matrix4.identity() | |
// ..setEntry(3, 2, 0.01) | |
// ..rotateX(math.pi * _animation.value * 3), | |
// child: const Icon( | |
// // PhysicalAppIcons.frameArrowDown, | |
// PhysicalAppIcons.calendar, | |
// size: 20, | |
// ), | |
// ), | |
Transform.rotate( | |
angle: -_animation.value * math.pi * 3, | |
child: const Icon( | |
PhysicalAppIcons.frameArrowDown, | |
size: 20, | |
), | |
), | |
], | |
), | |
onPressed: () { | |
opened = !opened; | |
}, | |
), | |
ClipRect( | |
child: Align( | |
heightFactor: _animation.value, | |
alignment: Alignment.bottomLeft, | |
child: child, | |
), | |
), | |
], | |
), | |
child: widget.child, | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment