- 주요 스택
- Navigation
- Button
- Slider
- 난수 생성
기초 레이아웃 작성
import 'package:flutter/material.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('랜덤 숫자 생성기'), IconButton( onPressed: () {}, icon: Icon( Icons.settings, ), ), ], ), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('1234'), Text('5678'), Text('9101'), ], ), ), /* * SizedBox 로 감싸서 width 를 꽉차게 만들어준다. * Container 로 감싸고 width 를 줘도 되지만, 뉘앙스 측면에서 SizedBox를 쓰는게 낫다. * Container는 내부에 더 많은 요소들을 가지고있지만, width나 height 정도만 조정할거라면 SizedBox 사용 * */ SizedBox( width: double.infinity, // width 무한대 // width: MediaQuery.of(context).size.width, child: ElevatedButton( onPressed: () {}, child: Text('생성하기'), ), ), ], ), ), ); } }
디자인 적용
import 'package:flutter/material.dart'; import 'package:lottery_number_randomly/constant/color.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: PRIMARY_COLOR, body: SafeArea( child: Padding( // css padding 사용법 // padding: const EdgeInsets.all(8.0), // padding: const EdgeInsets.only( // top: 8.0, // left: 8.0, // ), padding: const EdgeInsets.symmetric( horizontal: 16.0, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '랜덤 숫자 생성기', style: TextStyle( color: Colors.white, fontSize: 30.0, fontWeight: FontWeight.w700, ), ), IconButton( onPressed: () {}, icon: Icon( Icons.settings, color: RED_COLOR, ), ), ], ), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ 123, 456, 789, ] .map( (x) => Row( children: x .toString() .split('') .map( (y) => Image.asset( 'asset/img/$y.png', height: 70.0, width: 50.0, ), ) .toList(), ), ) .toList(), ), ), /* * SizedBox 로 감싸서 width 를 꽉차게 만들어준다. * Container 로 감싸고 width 를 줘도 되지만, 뉘앙스 측면에서 SizedBox를 쓰는게 낫다. * Container는 내부에 더 많은 요소들을 가지고있지만, width나 height 정도만 조정할거라면 SizedBox 사용 * */ SizedBox( width: double.infinity, // width 무한대 // width: MediaQuery.of(context).size.width, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: RED_COLOR, ), onPressed: () {}, child: Text('생성하기'), ), ), ], ), ), ), ); } }
랜덤 숫자 생성
숫자를 State에 정의하고, 그걸 변환하는 코드를 작성한다.
import 'dart:math'; import 'package:flutter/material.dart'; import 'package:lottery_number_randomly/constant/color.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { List<int> randomNumbers = [ 123, 456, 789, ]; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: PRIMARY_COLOR, body: SafeArea( child: Padding( // css padding 사용법 // padding: const EdgeInsets.all(8.0), // padding: const EdgeInsets.only( // top: 8.0, // left: 8.0, // ), padding: const EdgeInsets.symmetric( horizontal: 16.0, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '랜덤 숫자 생성기', style: TextStyle( color: Colors.white, fontSize: 30.0, fontWeight: FontWeight.w700, ), ), IconButton( onPressed: () {}, icon: Icon( Icons.settings, color: RED_COLOR, ), ), ], ), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: randomNumbers .asMap() .entries .map( (x) => Padding( padding: EdgeInsets.only( bottom: x.key == 2 ? 0 : 16.0), // 마지막 7,8,9 아래는 padding을 넣지 않음 child: Row( children: x.value .toString() .split('') .map( (y) => Image.asset( 'asset/img/$y.png', height: 70.0, width: 50.0, ), ) .toList(), ), ), ) .toList(), ), ), /* * SizedBox 로 감싸서 width 를 꽉차게 만들어준다. * Container 로 감싸고 width 를 줘도 되지만, 뉘앙스 측면에서 SizedBox를 쓰는게 낫다. * Container는 내부에 더 많은 요소들을 가지고있지만, width나 height 정도만 조정할거라면 SizedBox 사용 * */ SizedBox( width: double.infinity, // width 무한대 // width: MediaQuery.of(context).size.width, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: RED_COLOR, ), onPressed: () { final rand = Random(); final Set<int> newNumbers = {}; // 중복 숫자 제거하기 위해 Set while (newNumbers.length != 3) { final number = rand.nextInt(1000); // max 1000 이하 숫자 랜덤생성 newNumbers.add(number); } setState(() { randomNumbers = newNumbers.toList(); }); }, child: Text('생성하기'), ), ), ], ), ), ), ); } }
코드 정리
import 'dart:math'; import 'package:flutter/material.dart'; import 'package:lottery_number_randomly/constant/color.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { List<int> randomNumbers = [ 123, 456, 789, ]; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: PRIMARY_COLOR, body: SafeArea( child: Padding( padding: const EdgeInsets.symmetric( horizontal: 16.0, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _Header(), _Body(randomNumbers: randomNumbers), _Footer(onPressed: onRandomNumberGenerate), ], ), ), ), ); } void onRandomNumberGenerate() { final rand = Random(); final Set<int> newNumbers = {}; // 중복 숫자 제거하기 위해 Set while (newNumbers.length != 3) { final number = rand.nextInt(1000); // max 1000 이하 숫자 랜덤생성 newNumbers.add(number); } setState(() { randomNumbers = newNumbers.toList(); }); } } class _Header extends StatelessWidget { const _Header({super.key}); @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '랜덤 숫자 생성기', style: TextStyle( color: Colors.white, fontSize: 30.0, fontWeight: FontWeight.w700, ), ), IconButton( onPressed: () {}, icon: Icon( Icons.settings, color: RED_COLOR, ), ), ], ); } } class _Body extends StatelessWidget { final List<int> randomNumbers; const _Body({required this.randomNumbers, super.key}); @override Widget build(BuildContext context) { return Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: randomNumbers .asMap() .entries .map( (x) => Padding( padding: EdgeInsets.only( bottom: x.key == 2 ? 0 : 16.0), // 마지막 7,8,9 아래는 padding을 넣지 않음 child: Row( children: x.value .toString() .split('') .map( (y) => Image.asset( 'asset/img/$y.png', height: 70.0, width: 50.0, ), ) .toList(), ), ), ) .toList(), ), ); } } class _Footer extends StatelessWidget { final VoidCallback onPressed; // onPress 함수를 외부에서 받아오는 방법 외워둘것 const _Footer({required this.onPressed, super.key}); @override Widget build(BuildContext context) { return SizedBox( width: double.infinity, // width 무한대 child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: RED_COLOR, ), onPressed: onPressed, child: Text('생성하기'), ), ); } }