안녕하세요 독학코딩입니다. 오늘은 Flutter에서 위젯을 세로로 배치하는 방법에 대해서 배워보겠습니다. 그리고 세로 배치와는 비슷하지만 효과와 쓰임새가 다른 위젯 회전에 대해서도 배워보겠습니다.
Flutter RotatedBox
Flutter에서 위젯을 90도 혹은 180도 회전에서 배치하는 것은 상당히 간단합니다. 레이아웃을 세로 정의할 필요도 없습니다. 그저 RotatedBox만 사용하시면 됩니다.
class FirstRoute extends StatefulWidget {
const FirstRoute({Key? key}) : super(key: key);
@override
State<FirstRoute> createState() => _FirstRouteState();
}
class _FirstRouteState extends State<FirstRoute> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("로테이트박스"),
),
body: SingleChildScrollView(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
RotatedBox(
quarterTurns: 3,
child: Container(
color: Colors.black,
child: Text("본문 제목", style: TextStyle(fontSize: 40, color: Colors.white),),
),
),
SizedBox(
width: 300,
child: Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec egestas elit eget libero "
"congue faucibus. Nunc congue tincidunt tortor vitae malesuada. Donec ut leo pulvinar, scelerisque "
"sapien sit amet, commodo velit. Ut tempor consectetur nibh. Praesent vitae viverra odio. Nulla vel "
"risus a purus interdum auctor. Nam tincidunt blandit lorem, non placerat augue maximus ut."
"", style: TextStyle(fontSize: 20),),
)
],
),
),
);
}
}
시각적으로 잘 보이기 위해서 이것저것 많이 적었지만 핵심은 아래입니다.
RotatedBox(
quarterTurns: 3,
child: yourWidget(),
),
세로 배치하고 싶은 어떠한 위젯이든 RotatedBox로 감싸주면 됩니다. 여기서 회전의 각도를 quarterTurns가 설정합니다. 0을 원상태로 시작해서 1은 90도 2는 180도 3은 270도 이런 식으로 늘어납니다. 4 이상도 가능은 합니다만 굳이 그럴 이유는 없겠죠?
Flutter Transform.rotate
RotatedBox에 대해서 배웠으니, 이제 Transform.rotate에 대해서 배워보겠습니다. 위의 예제를 실행해보셨다면 아시겠지만, RotatedBox는 회전을 시키면 child 위젯의 레이아웃이 자동으로 현재 크기에 맞게 변경됩니다. 그래서 사용하기 편하다는 장점이 있습니다.
그와 반대로 Transform.rotate는 회전을 시켜도 레이아웃이 자동으로 변경되지 않습니다. 그러면 RotatedBox가 상이호환이라고 생각하실 수 있지만 그렇지 않습니다. 레이아웃이 계속해서 변경되면 안 되는 경우도 있기 때문입니다. 예를 들어 계속하여 회전하는 위젯을 만들어야 되는 경우입니다. 1도씩 움직일 때마다 레이아웃이 움직이면 좋지 않겠죠?
그래서 보통 RotatedBox는 회전하여 그 상태를 고정시켜야 되는 경우에 사용되고 Transform.rotate는 계속하여 회전하거나 90, 180, 270도 같이 정해진 값이 아니라 27도, 10도 같이 아주 세세하게 회전시켜야 할 때 사용합니다.
import 'dart:math' as math;
Transform.rotate(
angle: 45 * math.pi / 180, // 45 부분이 원하는 각도
child: Container(
color: Colors.black,
child: Text("본문 제목", style: TextStyle(fontSize: 40, color: Colors.white),),
),
),
특정 각도로 위젯을 회전하고 싶다면 위와 같이 사용하시면 됩니다. 여기서 원하는 각도는 angle의 45 부분에 작성하시면 됩니다.
물론 위에서 설명 드렸듯이 Transform.rotate를 이용하면 계속하여 회전하는 위젯을 만들 수 있습니다.
class _FirstRouteState extends State<FirstRoute> {
double angle = 0.0;
late Timer _timer;
@override
void initState() {
super.initState();
_timer = Timer.periodic(Duration(milliseconds: 100), (timer) {
doRotate();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Transform.rotate"),
),
body: SingleChildScrollView(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Transform.rotate(
angle: angle * math.pi / 180,
child: Container(
color: Colors.black,
child: Text("본문 제목", style: TextStyle(fontSize: 40, color: Colors.white),),
),
),
SizedBox(
width: 100,
child: Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec egestas elit eget libero "
"congue faucibus. Nunc congue tincidunt tortor vitae malesuada."
"", style: TextStyle(fontSize: 20),),
)
],
),
),
);
}
void doRotate() {
setState(() {
angle = angle + 3.0;
});
}
}
위에서 45도로 설정했던 부분을 변수 angle로 설정하고 그 angle이 계속하여 커지게 하면 됩니다. 그러기 위해서 angle에 일정 각도를 더하는 function, doRotate()를 만들고 doRotate()를 Timer를 이용하여 계속해서 호출해주면 됩니다. 엄청나게 어려운 방법은 아니지만, function을 계속해서 호출을 하게 되므로 계속해서 비효율적입니다.
Flutter AnimatedBuilder
조금더 편하게?? 아니면 조금 더 특이하게 위젯을 계속 회전하는 방법이 또 있습니다. AnimatedBuilder를 이용하는 방법입니다.
class FirstRoute extends StatefulWidget {
const FirstRoute({Key? key}) : super(key: key);
@override
State<FirstRoute> createState() => _FirstRouteState();
}
class _FirstRouteState extends State<FirstRoute>
with TickerProviderStateMixin { // with TickerProviderStateMixin 필수 추가
late final AnimationController _controller = AnimationController(vsync: this, duration: const Duration(seconds: 10),)..repeat();
@override
void dispose() { //이부분도 체크하셔야 합니다.
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Transform.rotate"),
),
body: SingleChildScrollView(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
AnimatedBuilder(
animation: _controller, // pass AnimationController to it
child: Container(
color: Colors.black,
child: Text("본문 제목", style: TextStyle(fontSize: 40, color: Colors.white),),
),
builder: (BuildContext context, Widget? child) {
return Transform.rotate(
angle: _controller.value * 2.0 * math.pi,
child: child,
);
},
),
SizedBox(
width: 100,
child: Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec egestas elit eget libero "
"congue faucibus. Nunc congue tincidunt tortor vitae malesuada."
"", style: TextStyle(fontSize: 20),),
)
],
),
),
);
}
}
한 번 테스트해보시는 걸 추천드립니다.
'Flutter > Flutter 위젯' 카테고리의 다른 글
Flutter - ImageFiltered, BackdropFilter, 이미지 흐림 효과 넣기 (0) | 2022.05.05 |
---|---|
Flutter - PhysicalModel, BoxDecoration, 위젯 그림자 넣기 (0) | 2022.05.03 |
Flutter - ExpansionPanel, ExpansionPanelList, 눌러서 열기, 확장 패널 (0) | 2022.04.28 |
Flutter - Theme, ThemeData, 테마 바꾸기 (0) | 2022.04.19 |
Flutter - RefreshIndicator, Pull to Refresh, 당겨서 새로고침 (0) | 2022.04.16 |
댓글