앞에서의 과정을 통해 lolcard(명함)를 구성하는 모든 정보를 얻었다.
이제는 정보를 바탕으로 lolcard을 만들어보자.
디자인
lolcard는 기본적으로 명함이다.
명함은 사용하는 사람의 정보를 잘 나타내야 한다고 생각한다.
따라서 눈에 잘 띄는 곳에 비교적 중요한 정보를 배치해야 한다.
(내가 생각한 정보의 중요도 : 소환사이름, 아이콘 > 랭크 정보 > 모스트 챔프 정보)
사람들은 세로 명함을 볼 때 주로 위에서 밑으로 읽는다고 생각했다.
따라서 소환사 이름과 아이콘을 위에 배치하고, 랭크 정보를 중간, 모스트 챔피언 성적을 아래에 배치했다.
랭크 정보나 모스트 챔프의 정보들은 깔끔하게 전달하기 위해 Card Widget를 사용했다.
카드를 디자인할 때 중요한 요소 중 하나는 위젯의 크기이다.
크기를 고정으로 해버리면(ex - 가로 300, 세로 500 이런 식)
디바이스마다 내부 위젯이 너무 커서 튀어나올 수도, 내부 위젯이 너무 작아 보기에 안 좋을 수도 있다.
이러한 이슈를 차단하기 위해 위젯의 가로 세로 값은 디바이스의 가로길이에 맞춰 설정했다.
//앱을 사용하는 디바이스의 가로 값을 얻는 코드
double width = MediaQuery.of(context).size.width;
위에 보이는 바와 같이 디바이스의 가로 값에 상수를 곱해 가로, 세로값을 정했다.
이렇게 함으로써 디바이스마다 명함의 크기차이는 있지만, 내부 위젯의 위치 및 크기 비율은 동일하다.
버튼(뒤로 가기, 홈, 캡처)
실제 앱을 작동해보면 위와 같은 화면이 나온다. 여기가 최종 결과물이 도출되는 화면이다.
아래에 보면 3가지 버튼이 있다. 아마 아이콘을 보면 감이 올 거다.
왼쪽부터 뒤로 가기 버튼, 홈으로 가기 버튼, 캡처 버튼이다.
뒤로가기 버튼은 단순히 pop이니 생략
홈 버튼은 아래의 코드로 이루어져 있다.
IconButton(
onPressed: () =>
{Navigator.popUntil(context, ModalRoute.withName("/"))},
icon: Icon(Icons.home),
iconSize: width * 0.15,
),
Navigator.popUntil(context, ModalRoute.withName("/")을 사용해서 처음 시작지점까지 pop을 한다.
캡처버튼은
screenshot라이브러리와 image_gallery_saver라이브러리를 사용하여 구현했다.
https://pub.dev/packages/screenshot
https://pub.dev/packages/image_gallery_saver
아래는 소스코드
일부분만 따오기 애매해서 다 들고 왔다.
class _CardCaptureState extends State<CardCapture> {
ScreenshotController screenshotController = ScreenshotController();
Saved(Uint8List image) async {
try {
await ImageGallerySaver.saveImage(image);
DoneDialog(context, 'Done!');
} catch (e) {
DoneDialog(context, e.toString());
}
}
DoneDialog(BuildContext context, String text) {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
title: Column(
children: [Text(text)],
),
actions: [
TextButton(
onPressed: () => {Navigator.pop(context)},
child: Text("OK"),
)
],
);
},
);
}
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Screenshot(
controller: screenshotController,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.white),
child: widget.frame,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed: () => {Navigator.of(context).pop()},
icon: Icon(Icons.arrow_back),
iconSize: width * 0.15,
),
IconButton(
onPressed: () =>
{Navigator.popUntil(context, ModalRoute.withName("/"))},
icon: Icon(Icons.home),
iconSize: width * 0.15,
),
IconButton(
onPressed: () {
screenshotController.capture().then((Uint8List? image) {
Saved(image!);
});
},
icon: Icon(Icons.camera_alt),
iconSize: width * 0.15,
),
],
)
],
),
));
}
}
간단하게 말하면 캡처하고 싶은 위젯을 Screenshot으로 감싼 후, controller를 집어넣고,
capture함수를 통해 얻은 image를 ImageGallertSaver를 사용해 갤러리에 저장한다고 말할 수 있겠다.
이렇게 해서 LOLCard 앱의 처음부터 끝까지 다 살펴봤다.
사실 오늘 설명한 부분 중 하나인 디자인이 앱 제작 중 가장 많은 시간을 잡아먹었다.
기술적인 문제가 있었다기 보단 어떤 디자인이 깔끔하고 보기 좋을지 고민하다 보니..
디자인이 생각보다 어려웠다 ㅎㅎ
여하튼 이렇게 해서 앱 제작이 끝이 났다.
하지만 끝이 아니다. 앱 제작을 했으면 배포까지 해야 진짜 끝이다!
따라서 다음 글은 구글플레이에 출시하는 것에 대한 내용으로 해서 올리겠다.
'프로젝트 > LOL Card' 카테고리의 다른 글
롤 명함 앱 만들기#9-결과물&프로젝트 후기 (1) | 2023.01.11 |
---|---|
롤 명함 앱 만들기#8-구글 플레이 등록 (0) | 2023.01.11 |
롤 명함 앱 만들기#6-추가 정보 입력 (0) | 2022.12.16 |
LOLCard's privacy policy (0) | 2022.12.14 |
롤 명함 앱 만들기#5-소환사 데이터 가져오기 (0) | 2022.12.07 |