본문 바로가기
Flutter/Flutter FAQ

Flutter 플러터에서 축소되는 요소를 어떻게 애니메이션화할 수 있을까요?, How to Animate Collapsing Elements in Flutter

by 베타코드 2023. 9. 26.
반응형

질문


사용자가 다른 위젯 (형제 또는 부모)을 탭 할 때 위젯을 확장하고 축소하려면 어떻게해야합니까?

new Column(
    children: <Widget>[
        new header.IngridientHeader(
            new Icon(
                Icons.fiber_manual_record,
                color: AppColors.primaryColor
            ),
            '음성 트랙 1'
        ),
        new Grid()
    ],
)

사용자가 header.IngridientHeader를 탭 할 수 있도록하고 Grid 위젯은 토글되어야합니다 (표시되지 않으면 숨겨지고 그 반대도 마찬가지입니다).

나는 부트 스트랩에서 축소와 비슷한 작업을하려고합니다. getbootstrap.com/docs/4.0/components/collapse

header.IngridientHeader 위젯은 항상 제자리에 있어야합니다. grid는 스크롤 가능한 (가로) 위젯입니다.


답변


위젯을 제로 높이 또는 제로 너비로 축소하려는 경우 축소 시 오버플로우되는 자식이 있다면 SizeTransition 또는 ScaleTransition을 추천합니다.

다음은 ScaleTransition 위젯이 사용되어 검은 버튼과 상태 텍스트를 포함하는 컨테이너를 축소하는 예입니다. 다음 구조를 얻기 위해 열과 함께 내가 만든 ExpandedSection 위젯을 사용했습니다. ScaleTransition 위젯의 예

SizeTransition 위젯과 함께 애니메이션을 사용하는 위젯의 예:

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();
  }

  ///애니메이션 설정
  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
    );
  }
}

AnimatedContainer도 작동하지만 자식이 제로 너비 또는 제로 높이로 조절할 수 없으면 Flutter에서 오버플로우에 대해 경고할 수 있습니다.

반응형

댓글