앞에서 설명했던 것과 같이 제일 큰 노란색 박스를 먼저 만들어주고 점점 세부적인 디테일을 구현 해 줄 것이다.
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'circle_diagonal_line_painter .dart';
import 'each_button.dart';
class WheelButton extends StatefulWidget {
final double bottom; // 위젯의 위치를 설정하세요
final double containerSize; // 위젯의 크기를 설정하세요
final Color containerBgColor; // 버튼의 색상
final Color borderColor; // border 색상
final double borderWidth; // border 두께
final List<EachButton> buttons; // 최대 8개까지의 버튼을 넣을 수 있습니다
final bool showLines; // 버튼 사이사이에 라인을 그릴것인가요 아닌가요
final Widget? centerWidget; // 중앙 아이콘 입니다.
WheelButton({
this.bottom = 0,
this.containerSize = 300,
this.containerBgColor = Colors.white,
this.borderColor = const Color(0xFFE7E6E4),
this.borderWidth = 1.0,
required this.buttons,
this.showLines = false,
this.centerWidget,
}) : assert(buttons.length <= 8, '버튼은 최대 8개까지 가능합니다.');
@override
_WheelButtonState createState() => _WheelButtonState();
}
class _WheelButtonState extends State< WheelButton> {
late List<EachButton> _currentButtons; // 현재 화면에 표시될 버튼들
@override
void initState() {
super.initState();
_currentButtons = widget.buttons;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: Stack(
alignment: Alignment.center,
children: [
Positioned(
bottom: widget.bottom,
child: GestureDetector(
//버튼을 이동시킬 액션을 구현 중
child: Container(
width: widget.containerSize,
height: widget.containerSize,
decoration: BoxDecoration(
color: widget.containerBgColor,
shape: BoxShape.circle,
border: Border.all(
color: widget.borderColor, width: widget.borderWidth),
),
child: Stack(
alignment: Alignment.center,
children: [
if( widget.showLines )
CustomPaint(
size: Size(widget.containerSize,widget.containerSize ),
painter : CircleDiagonalLinePainter(numberOfButtons : widget.buttons.length),
), //버튼 사이사이 선이 있는지 없는지
Stack(
alignment: Alignment.center,
children: _buildPositionedButtons(),
),
// 중앙 아이콘
widget.centerWidget ??
Container(
width: 100,
height: 100,
decoration: const BoxDecoration(
color: Color(0xFF373430),
shape: BoxShape.circle,
),
child: Center(
child: Container(
width: 44,
height: 44,
decoration: const BoxDecoration(
color: Color(0xFFE6E2DB),
shape: BoxShape.circle,
),
child: GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
),
),
),
),
],
),
),
),
)
],
));
}
//버튼을 하나씩 그려줄 함수
List<Widget> _buildPositionedButtons() {
List<Widget> positionedButtons = [];
double roundStep = 360 / _currentButtons.length;
for (int i = 0; i < _currentButtons.length; i++) {
double angle = roundStep * i;
double rad = angle * (pi / 180);
double xPos = (widget.containerSize / 2) * 0.7 * -cos(rad);
double yPos = (widget.containerSize / 2) * 0.7 * -sin(rad);
positionedButtons.add(Positioned(
left: widget.containerSize / 2 + xPos - 28,
top: widget.containerSize / 2 + yPos - 28,
child: _currentButtons[i],
));
}
return positionedButtons;
}
}
'Flutter' 카테고리의 다른 글
Flutter pub.dev 에 패키지 배포하기 (1) | 2024.10.16 |
---|---|
Flutter 네이버 그린닷 구현 (feat. 네이버 스마트렌즈) _ 1 (0) | 2024.10.07 |
Flutter Textfield 키보드로 focus 이동 시키기 (feat. 로그인 창) (0) | 2024.09.26 |
Flutter API 통신을 간편하게 해주는 dio 라이브러리 (0) | 2024.09.20 |
ModalBarrier 활용하기 (0) | 2024.09.02 |