Floating에서 붕괴하는 요소를 애니메이션화하는 방법
사용자가 애니메이션으로 다른 위젯(형제 또는 상위)을 탭할 때 위젯을 확장하고 축소하려면 어떻게 해야 합니까?
new Column(
children: <Widget>[
new header.IngridientHeader(
new Icon(
Icons.fiber_manual_record,
color: AppColors.primaryColor
),
'Voice Track 1'
),
new Grid()
],
)
나는 사용자가 위젯을 누른 다음 위젯을 전환할 수 있기를 바란다(표시되는 경우 숨기기 또는 그 반대).
나는 부트스트랩의 붕괴와 비슷한 것을 하려고 한다.
위젯은 항상 제자리에 있어야 합니다. 는 스크롤 가능한(수평) 위젯입니다.
당신은 위젯을 찾고 있는 것 같습니다. 이렇게 하면 위젯을 표시하거나 토글할 때 숨길 수 있는 헤더 및 속성과 동일한 속성이 사용됩니다. 당신은 그것을 사용하는 방법의 예를 찾을 수 있습니다.
간단한 사용 예:
new ExpansionTile(title: new Text("Numbers"),
children: <Widget>[
new Text("Number: 1"),
new Text("Number: 2"),
new Text("Number: 3"),
new Text("Number: 4"),
new Text("Number: 5")
],
),
그게 도움이 되길 바래요!
또는 를 사용하여 이 동작을 모방할 수 있습니다.
class AnimateContentExample extends StatefulWidget {
@override
_AnimateContentExampleState createState() => new _AnimateContentExampleState();
}
class _AnimateContentExampleState extends State<AnimateContentExample> {
double _animatedHeight = 100.0;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("Animate Content"),),
body: new Column(
children: <Widget>[
new Card(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new GestureDetector(
onTap: ()=>setState((){
_animatedHeight!=0.0?_animatedHeight=0.0:_animatedHeight=100.0;}),
child: new Container(
child: new Text("CLICK ME"),
color: Colors.blueAccent,
height: 25.0,
width: 100.0,
),),
new AnimatedContainer(duration: const Duration(milliseconds: 120),
child: new Text("Toggle Me"),
height: _animatedHeight,
color: Colors.tealAccent,
width: 100.0,
)
],
) ,
)
],
),
);
}
}
위젯을 0 높이 또는 0 너비로 축소하려면 축소 시 오버플로되는 자식이 있는 위젯을 축소하는 것이 좋습니다.
다음은 4개의 검은색 단추와 상태 텍스트의 컨테이너를 축소하는 데 사용되는 Scale Transition 위젯의 예입니다. 내 확장 섹션 위젯은 열과 함께 다음 구조를 가져오는 데 사용됩니다.
크기 전환 위젯과 함께 애니메이션을 사용하는 위젯의 예:
class ExpandedSection extends StatefulWidget {
final Widget child;
final bool expand;
ExpandedSection({this.expand = false, required this.child});
@override
_ExpandedSectionState createState() => _ExpandedSectionState();
}
class _ExpandedSectionState extends State<ExpandedSection> with SingleTickerProviderStateMixin {
late AnimationController expandController;
late Animation<double> animation;
@override
void initState() {
super.initState();
prepareAnimations();
_runExpandCheck();
}
///Setting up the animation
void prepareAnimations() {
expandController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 500)
);
animation = CurvedAnimation(
parent: expandController,
curve: Curves.fastOutSlowIn,
);
}
void _runExpandCheck() {
if(widget.expand) {
expandController.forward();
}
else {
expandController.reverse();
}
}
@override
void didUpdateWidget(ExpandedSection oldWidget) {
super.didUpdateWidget(oldWidget);
_runExpandCheck();
}
@override
void dispose() {
expandController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizeTransition(
axisAlignment: 1.0,
sizeFactor: animation,
child: widget.child
);
}
}
또한 작동하지만 어린이가 너비나 높이가 0이 아닌 크기로 조정되지 않을 경우 Flutter가 오버플로에 대해 불평할 수 있습니다.
출력:
코드:
class FooPageState extends State<SoPage> {
static const _duration = Duration(seconds: 1);
int _flex1 = 1, _flex2 = 2, _flex3 = 1;
@override
Widget build(BuildContext context) {
final total = _flex1 + _flex2 + _flex3;
final height = MediaQuery.of(context).size.height;
final height1 = (height * _flex1) / total;
final height2 = (height * _flex2) / total;
final height3 = (height * _flex3) / total;
return Scaffold(
body: Column(
children: [
AnimatedContainer(
height: height1,
duration: _duration,
color: Colors.red,
),
AnimatedContainer(
height: height2,
duration: _duration,
color: Colors.green,
),
AnimatedContainer(
height: height3,
duration: _duration,
color: Colors.blue,
),
],
),
);
}
}
@Adam Jonson 덕분에, 그의 대답은 나의 문제를 해결했다. 그리고 이것은 사용법에 대한 데모입니다. 도움이 되길 바랍니다.
class ExpandedSection extends StatefulWidget {
final Widget child;
final bool expand;
ExpandedSection({this.expand = false, this.child});
@override
_ExpandedSectionState createState() => _ExpandedSectionState();
}
class _ExpandedSectionState extends State<ExpandedSection>
with SingleTickerProviderStateMixin {
AnimationController expandController;
Animation<double> animation;
@override
void initState() {
super.initState();
prepareAnimations();
_runExpandCheck();
}
///Setting up the animation
void prepareAnimations() {
expandController =
AnimationController(vsync: this, duration: Duration(milliseconds: 500));
animation = CurvedAnimation(
parent: expandController,
curve: Curves.fastOutSlowIn,
);
}
void _runExpandCheck() {
if (widget.expand) {
expandController.forward();
} else {
expandController.reverse();
}
}
@override
void didUpdateWidget(ExpandedSection oldWidget) {
super.didUpdateWidget(oldWidget);
_runExpandCheck();
}
@override
void dispose() {
expandController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizeTransition(
axisAlignment: 1.0, sizeFactor: animation, child: widget.child);
}
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Home(),
),
);
}
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool _expand = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
Header(
onTap: () {
setState(() {
_expand = !_expand;
});
},
),
ExpandedSection(child: Content(), expand: _expand,)
],
);
}
}
class Header extends StatelessWidget {
final VoidCallback onTap;
Header({@required this.onTap});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
color: Colors.cyan,
height: 100,
width: double.infinity,
child: Center(
child: Text(
'Header -- Tap me to expand!',
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
);
}
}
class Content extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.lightGreen,
height: 400,
);
}
}
애니메이션 컨트롤러가 필요 없는 또 다른 솔루션은 의 위젯을 전환 작성기로 사용하는 것입니다.
다음은 간단한 예입니다:
AnimatedSwitcher(
duration: Duration(milliseconds: 300),
transitionBuilder: (child, animation) {
return SizeTransition(sizeFactor: animation, child: child);
},
child: expanded ? YourWidget() : null,
)
물론 애니메이션의 곡선 및 레이아웃 작성기를 사용자 지정할 수 있습니다.
'개발하자' 카테고리의 다른 글
| 파이썬에서 dir()와 __dict_의 가장 큰 차이점은 무엇입니까 (0) | 2023.06.21 |
|---|---|
| 복제 컨트롤러와 Kubernetes에 배포 (0) | 2023.06.21 |
| 흐름형 CLI 도구에 해당하는 TypeScript가 있나요? (0) | 2023.06.20 |
| 리눅스 터미널에서 모든 셀에서 주피터 노트북의 출력을 지우는 방법은 무엇입니까? (0) | 2023.06.19 |
| 클러스터 외부의 응용 프로그램에서 kubernetes의 게시물 액세스 (0) | 2023.06.18 |

