본문 바로가기
Flutter

[Flutter] UI(4) - ExpansionTile, Listile 아이콘 앞에 위치시키기(animation)

by 아마도개발자 2023. 12. 25.

 

ExpansionTile Widget을 이용해서 ui를 만들던 중 tailing에 위치한 아이콘을 leading 위치로 옮겨서 표현해야 하는 일이 생겼다. 애니메이션 효과 없이 단순히 위치를 옮기려면 ExpansionTile의 tailing에 SizedBox()를 넣어주고, leading에 아이콘을 넣어주면 끝이나지만, 기존에 tailing이 갖고 있던 회전 에니메이션을 그대로 추가해주기 위해서는 다른 위젯들의 활용이 필요하다.

 

  • 코드
class TreeView extends StatefulWidget {
  final String node;
  final List<TreeModel>? children;
  final bool initiallyExpanded;
  const TreeView({
    Key? key,
    required this.node,
    this.children,
    this.initiallyExpanded = false,
  }) : super(key: key);

  @override
  State<TreeView> createState() => _TreeViewState();
}

class _TreeViewState extends State<TreeView>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  bool _isExpanded = false;
  @override
  void initState() {
    super.initState();
    _controller = AnimationController(duration: kExpand, vsync: this);
    _animation = Tween<double>(begin: 0.0, end: 0.5).animate(_controller);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          child: ExpansionTile(
            leading: RotationTransition(
              turns: _animation,
              child: const Icon(Icons.expand_more),
            ),
            title: Text('${widget.node}'),
            trailing: SizedBox(),
            onExpansionChanged: (value) {
              setState(() {
                _isExpanded = value;
                if (value) {
                  _controller.forward();
                } else {
                  _controller.reverse();
                }
              });
            },
            // onExpansionChanged: ,
          ),
        ),
      ],
    );
  }
}

 

  1. SingleTickerProviderStateMixin을 포함하여 애니메이션을 제어하기 위한 필수 기능을 추가한다.
  2. _controller는 애니메이션을 제어하기 위한 컨트롤러이다. vsync에는 this를 사용하여 현재 위젯의 상태를 나타내는 객체를 전달한다. ( kExpand = Duration(milliseconds: 200) )
  3. _animation은 애니메이션을 정의하는데 사용되며, 0부터 0.5까지의 값을 변화시킵니다. 이 값은 회전 애니메이션에 사용된다.
  4. leading에 있는 아이콘을 애니메이션으로 회전시키기 위해 RotationTransition 위젯을 사용.
  5. _animation을 RotationTransition의 turns 속성으로 설정하여 애니메이션을 적용한다.
  6. onExpansionChanged 콜백은 ExpansionTile의 확장 상태가 변경될 때마다 호출된다. 이 때, _isExpanded 상태를 업데이트하고, 상태에 따라 애니메이션을 시작하거나 역재생한다.

 

  • 실행화면