for, for in, foreach, while문

List<type>.generate

void basicLoop(){
  List<String> rainbow = ['1','2','3','4','5','6'];

  for(int i=0; i<rainbow.length; i++){
    print(rainbow[i]);
  }

  for(String x in rainbow){
    print(x);
  }

  rainbow.forEach((name){
    print(name);
  });
}

void main(){
  basicLoop();
  return;
}

 

[로또번호 생성기 ver_1]

아래 프로그램은 list자료형의 특성상 random으로 값을 생성할 때 중복된 값을 허용함

import 'dart:math';

List<int> lottoNmber(){
  var random = Random();
  List<int> lottoList = [];
  var num;

  for(int i=0; i<6; i++){
    num = random.nextInt(45) + 1;
    lottoList.add(num);
  }

  print('당첨번호');
  print(lottoList);

  return lottoList;
}

List<int> myNumber(){
  var random = Random();
  List<int> myList = [];
  var num;

  for(int i=0; i<6; i++){
    num = random.nextInt(45) + 1;
    myList.add(num);
  }

  print('내 추첨번호');
  print(myList);

  return myList;
}

void checkNumber(lottoList, myList){

  int match = 0;

  for(int lotto in lottoList){
    for(int myNum in myList){
      if(lotto == myNum){
        match++;
        print('당첨번호: $lotto');
      }
      //print("로또번호 = $lotto");
      //print("내 추첨번호 = $myNum");
    }
  }
  print("$match개의 당첨번호가 있습니다.");
}

void main(){
  List<int>lottoFinal = lottoNmber();
  List<int>myFinal = myNumber();

  checkNumber(lottoFinal, myFinal);

  return;
}

 

[로또번호 생성기 ver_2]

set을 사용해서 중복된 값 제외하기

import 'dart:math';

Set<int> lottoNmber(){
  final random = Random();
  final Set<int> lottoSet = {};

  while(lottoSet.length != 6){
    lottoSet.add(random.nextInt(45)+1);
  }
  print('당첨번호');
  print(lottoSet.toList());

  return lottoSet;
}

Set<int> myNumber(){
  final random = Random();
  final Set<int> mySet = {};

  while(mySet.length != 6){
    mySet.add(random.nextInt(45)+1);
  }

  print('내 추첨번호');
  print(mySet.toList());
  return mySet;
}

void checkNumber(lottoSet, mySet){

  int match = 0;

  for(int lotto in lottoSet){
    for(int myNum in mySet){
      if(lotto == myNum){
        match++;
        print('당첨번호: $lotto');
      }
      //print("로또번호 = $lotto");
      //print("내 추첨번호 = $myNum");
    }
  }
  print("$match개의 당첨번호가 있습니다.");
}

void main(){
  Set<int>lottoFinal = lottoNmber();
  Set<int>myFinal = myNumber();

  checkNumber(lottoFinal, myFinal);

  return;
}

 

리스트 제너레이터

List<int>.generate(45, (i) => i+1);

예시

void main(){
  var text = List<int>.generate(45, (i) => i+1);
  print(text);
}

 

 

dart언어 cascade notation

class Person{
  String? name;
  int? age;

  void set(int x){
    age = x;
  }

  void show(){
    print(name);
    print(age);
  }
}

void main(){
  Person p1 = Person();
  p1.set(30);
  p1.name = "Lee";
  p1.show();

  Person p2 = Person();
  p2..set(20)..name = "Kim"..show();

  Person p3 = Person();
  p3..set(40)
    ..name="Park"
    ..show();
}

 

cascade 표기법을 활용해서 랜덤한 lotto 숫자 6개 뽑아내기

void main(){
  var test = (List<int>.generate(45, (i) => i+1)..shuffle()).sublist(0,6);
  print(test);
}

 

다시 로또프로그램 만들기

 

 

shutdown -s -f -t 14000

shutdown -r -f -t 14000

shutdown -a

https://mozi.tistory.com/402

https://mockaroo.com/

 

Mockaroo - Random Data Generator and API Mocking Tool | JSON / CSV / SQL / Excel

Mock your back-end API and start coding your UI today. It's hard to put together a meaningful UI prototype without making real requests to an API. By making real requests, you'll uncover problems with application flow, timing, and API design early, improvi

mockaroo.com

 

 

 

Future 클래스는 비동기 작업을 할 때 사용

Future는 일정 소요시간 후에 실제 데이터나 에러를 반환

async클래스는 await 메서드를 가지고 잇으며, await메소드로 선언된 메소드는 응답이 처리될 때까지 대기하는 동기식으로 처리가 가능(데이터를 수신해서 다음 과정을 처리할 때 사용)

 

1.1 일반적인 동기적 상황(Sync)

import 'dart:io';

void main(){
  showData();
}

void showData(){
  startTask();
  acessData();
  fetchData();
}

void startTask(){
  String info1 = '요청수행 시작';
  print(info1);
}

void acessData(){
  Duration time = Duration(seconds: 3);
  sleep(time);
  String info2 = '데이터에 접속중';
  print(info2);
}

void fetchData(){
  String info3 = '잔액은 8,500원 입니다.';
  print(info3);
}

 

1.2 일반적인 비동기적상황(Async)

import 'dart:io';

void main(){
  showData();
}

void showData(){
  startTask();
  acessData();
  fetchData();
}

void startTask(){
  String info1 = '요청수행 시작';
  print(info1);
}

void acessData(){
  Duration time = Duration(seconds: 3);

  if(time.inSeconds>2){
    //sleep(time);
    Future.delayed(time, (){
      String info2 = "데이터 처리 완료";
      print(info2);
    });
  }else{
    String info2 = "데이터를 가져왔습니다.";
    print(info2);
  }
}

void fetchData(){
  String info3 = '잔액은 8,500원 입니다.';
  print(info3);
}

 

2.1 비동기처리로 인한 문제 발생

fetch함수가 acessData()함수의 리턴값이 필요한 상황

import 'dart:io';

void main(){
  showData();
}

void showData(){
  startTask();
  String account = acessData();
  fetchData(account);
}

void startTask(){
  String info1 = '요청수행 시작';
  print(info1);
}

String acessData(){
  String account="";

  Duration time = Duration(seconds: 3);

  if(time.inSeconds>2){
    //async로 처리되는 부분
    Future.delayed(time, (){
      account = "8,500만원";
      print(account);
    });
  }else{
    String info2 = "데이터를 가져왔습니다.";
    print(info2);
  }
  return account;
}

void fetchData(String account){
  String info3 = '잔액은 $account원 입니다.';
  print(info3);
}

 

2.2 문제 해결

 - 우선 acessData함수는 비동기 함수로 Future.delayed함수가 리턴이 된 후 나머지 문장이 실행된다.

 - Future.delayed함수 안에서 account값이 할당이 되고  그 값을 리턴하는데 Future<string>타입이다.

   -> 리턴타입이 Future<string>라는 것은 일정 시간 후에 Future타입을 리턴하는데 이는 문자열을 의미/ 즉, 비동기 처리를 진행하고 일정 시간 후 string을 리턴한다는 뜻

 - Future<string>타입을 리턴하는 acessData함수는 결국 showData함수에서 호출되므로 showData함수도 비동기 처리를 해줘야 한다.

import 'dart:io';

void main(){
  showData();
}

void showData() async{
  startTask();
  String account = await acessData();
  fetchData(account);
}

void startTask(){
  String info1 = '요청수행 시작';
  print(info1);
}

Future<String> acessData() async{
  String account="";

  Duration time = Duration(seconds: 3);

  if(time.inSeconds>2){
    //async로 처리되는 부분
    await Future.delayed(time, (){
      account = "8,500만원";
      print(account);
    });
  }else{
    String info2 = "데이터를 가져왔습니다.";
    print(info2);
  }
  return account;
}

void fetchData(String account){
  String info3 = '잔액은 $account원 입니다.';
  print(info3);
}

코드 리팩토링이란?

코드를 유지 보수하기 좋게 바꾸는 것

가독성도 높일 수 있고 불필요한 중복을 피할 수 있다.
이는 결국 다른 사람과의 협업에도 도움이 된다.

 

참고: https://velog.io/@qkrtnfks128/Flutter-%EC%BD%94%EB%93%9C-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81refactoring

 

[Flutter] 코드 리팩토링(refactoring)

코드를 간결하게~~!!

velog.io

 

 

 

로그인 페이지를 통한 코드 리팩토링

main.dart

import 'package:flutter/material.dart';
import 'login_app/login.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firebase login app',
      home: LogIn(),
    );
  }
}

 

my_button.dart

유사한 모양의 버튼을 여러개 사용하는 상황에서 

MyButton이라는 클래스를 만들어서 변경요소인 image, text, color, radius, VoidCallback 함수 를 매개변수로 생성자를 호출하면 동일한 버튼을 찍어낼 수 있도록 함.

required 문법에 대한 이해 필요

import 'package:coderefactoring/login_app/login.dart';
import 'package:flutter/material.dart';

class MyButton extends StatelessWidget {
  MyButton({Key? key, required this.image, required this.text, required this.color, required this.radius, required this.onPressed}) : super(key: key);

  final Widget image;
  final Widget text;
  final Color color;
  final double radius;
  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {

    return ButtonTheme(
      height: 50.0,
      child: ElevatedButton(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            image,
            text,
            Opacity(
              opacity: 0.0,
              child: Image.asset('images/glogo.png'),
            ),
          ],
        ),
        style: ElevatedButton.styleFrom(
            backgroundColor: color
        ),
        onPressed: onPressed,
      ),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.all(
          Radius.circular(radius),
        ),
      ),
    );
  }
}

 

 

login.dart

MyButton객체를 이용해서 버튼을 쉽게 생성

import 'package:coderefactoring/my_button/my_button.dart';
import 'package:flutter/material.dart';

class LogIn extends StatelessWidget {
  const LogIn({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blue,
        title: Text(
          'Sign In',
          style: TextStyle(color: Colors.white),
        ),
        centerTitle: true,
        elevation: 0.2,
      ),
      body: buildButton(),
    );
  }

  Widget buildButton() {
    return Padding(
      padding: EdgeInsets.all(16.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          MyButton(
              image: Image.asset('images/glogo.png'),
              text: Text(
                'Login with Google',
                style: TextStyle(color: Colors.black87, fontSize: 15.0),
              ),
              color: Colors.white,
              radius: 4.0,
              onPressed: () {}),
          SizedBox(
            height: 10.0,
          ),
          MyButton(
              image: Image.asset('images/flogo.png'),
              text: Text(
                'Login with Facebook',
                style: TextStyle(color: Colors.white, fontSize: 15.0),
              ),
              color: Color(0xFF334D92),
              radius: 4.0,
              onPressed: () {}),
          SizedBox(
            height: 10.0,
          ),
          MyButton(
              image: Icon(
                Icons.mail,
                color: Colors.white,
              ),
              text: Text(
                'Login with Email',
                style: TextStyle(color: Colors.white, fontSize: 15.0),
              ),
              radius: 4.0,
              color: Colors.green,
              onPressed: () {},
          ),

          SizedBox(
            height: 10.0,
          ),
        ],
      ),
    );
  }
}

 

 

 

1. Image.asset('경로')

2. Image(image: AssetImage('경로')

 

'플로터(Flutter) > CheetSheet' 카테고리의 다른 글

focus  (0) 2023.01.17
Flutter Snackbar사용법  (0) 2023.01.17

 

focus

 

참고

https://dev-gold.tistory.com/114

 

[Flutter]Focus and text fields 포커스 및 텍스트 필드

텍스트 필드가 선택되고 입력을 받을 수 있을 때, 포커스를 갖는다고 합니다 일반적으로, 사용자는 탭하여 텍스트 필드에 포커스를 이동시키고, 개발자는 아래 레시피에 설명되어있는 방식으로

dev-gold.tistory.com

https://velog.io/@sunwonsw95/Flutter-Focus-widget

 

[Flutter] Focus widget

모바일 앱의 다양한 입력필드를 보면 입력 필드에 포커스가 맞춰져 있는 동안 입력 필드 내 특정 아이콘이나 버튼, 텍스트가 활성화 되는 경우가 상당히 많다.나 역시 플러터의 TextFormField위젯을

velog.io

 

'플로터(Flutter) > CheetSheet' 카테고리의 다른 글

이미지 처리  (0) 2023.01.17
Flutter Snackbar사용법  (0) 2023.01.17

 

1. main.dart에서 우리가 눈여겨 볼 것은 총 3가지이다.

  가. 페이지이동

 

  나. Textfield 컨트롤

다. 스낵바 사용하기

 - 영상강좌에서는 SnackBar를 사용하기 위해 build위젯으로 감싸서 context를 만들어주는 부분이 있다 하지만 개선된 버전에서는 build위젯으로 감싸서 context를 만들어주는 부분이 필요없다.

빌더위젯으로 감싸지 않고 바로 처리
스낵바 구현 부분

 

 

main.dart

import 'package:flutter/material.dart';
import 'dice.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Dice game',
      home: LogIn(),
    );
  }
}

class LogIn extends StatefulWidget {
  const LogIn({Key? key}) : super(key: key);

  @override
  State<LogIn> createState() => _LogInState();
}

class _LogInState extends State<LogIn> {
  TextEditingController controller = TextEditingController();
  TextEditingController controller2 = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Log in'),
          backgroundColor: Colors.redAccent,
          centerTitle: true,
          leading: IconButton(
            icon: Icon(Icons.menu),
            onPressed: () {},
          ),
          actions: [IconButton(onPressed: () {}, icon: Icon(Icons.menu))],
        ),
        body: GestureDetector(
          onTap: (){
            FocusScope.of(context).unfocus(); //키보드 없애기
          },
          child: SingleChildScrollView(
                //스크롤 뷰로 구성
                child: Column(
                  children: [
                    Padding(padding: EdgeInsets.only(top: 50)),
                    Center(
                        child: Image(
                      image: AssetImage('image/chef.gif'),
                      width: 170.0,
                      height: 190.0,
                    )),
                    Form(
                        child: Theme(
                            data: ThemeData(
                                primaryColor: Colors.teal,
                                inputDecorationTheme: InputDecorationTheme(
                                    labelStyle: TextStyle(
                                        color: Colors.teal, fontSize: 15.0))),
                            child: Container(
                              padding: EdgeInsets.all(40.0),
                              child: Column(
                                children: [
                                  TextField(
                                    autofocus: true,
                                    controller: controller,
                                    decoration: InputDecoration(
                                        labelText: 'Enter "dice"'),
                                    keyboardType: TextInputType.emailAddress,
                                  ),
                                  TextField(
                                    controller: controller2,
                                    decoration: InputDecoration(
                                        labelText: 'Enter Password'),
                                    keyboardType: TextInputType.text,
                                    obscureText: true,
                                  ),
                                  SizedBox(
                                    height: 40,
                                  ),
                                  ButtonTheme(
                                      minWidth: 100,
                                      height: 50,
                                      child: ElevatedButton(
                                          style: ElevatedButton.styleFrom(
                                              backgroundColor:
                                                  Colors.orangeAccent),
                                          onPressed: () {
                                            if (controller.text == 'dice' &&
                                                controller2.text == '1234') {
                                              Navigator.push(
                                                  context,
                                                  MaterialPageRoute(
                                                      builder: (BuildContext
                                                              context) =>
                                                          Dice())); //순한맛22번강좌
                                            } else if (controller.text !=
                                                    'dice' &&
                                                controller2.text == '1234') {
                                              showSnackBar2(context);
                                            } else if (controller.text ==
                                                    'dice' &&
                                                controller2.text != '1234') {
                                              showSnackBar3(context);
                                            } else {
                                              showSnackBar(context);
                                            }
                                          },
                                          child: Icon(Icons.arrow_forward,
                                              color: Colors.white, size: 35.0)))
                                ],
                              ),
                            )))
                  ],
                ),
              ),
        )
        );
  }
}

void showSnackBar(BuildContext context) {
  ScaffoldMessenger.of(context).showSnackBar(SnackBar(
    content: Text(
      '로그인 정보를 다시 확인하세요.',
      textAlign: TextAlign.center,
    ),
    duration: Duration(seconds: 2),
    backgroundColor: Colors.blue,
  ));
}

void showSnackBar2(BuildContext context) {
  ScaffoldMessenger.of(context).showSnackBar(SnackBar(
    content: Text(
      '비밀번호가 일치하지 않습니다.',
      textAlign: TextAlign.center,
    ),
    duration: Duration(seconds: 2),
    backgroundColor: Colors.blue,
  ));
}

void showSnackBar3(BuildContext context) {
  ScaffoldMessenger.of(context).showSnackBar(SnackBar(
    content: Text(
      'dice의 철자를 확인하세요.',
      textAlign: TextAlign.center,
    ),
    duration: Duration(seconds: 2),
    backgroundColor: Colors.blue,
  ));
}

dice.dart

- fluttertoast사용

import 'package:flutter/material.dart';
import 'dart:math';
import 'package:fluttertoast/fluttertoast.dart';

class Dice extends StatefulWidget {
  const Dice({Key? key}) : super(key: key);

  @override
  State<Dice> createState() => _DiceState();
}

class _DiceState extends State<Dice> {
  int leftDice = 1;
  int rightDice = 2;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.redAccent,
      appBar: AppBar(
        backgroundColor: Colors.redAccent,
        title: Text('Dice Game'),
      ),
      body: Center(
        //center위젯 안에서 Column이나 Row를 사용할 때
        //중앙 정렬하려면 MainAxisAlignment.center사용
        //순한맛강좌 21강
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Padding(
              padding: const EdgeInsets.all(32),
              child: Row(
                children: [
                  //Expanded위젯은 컬럼이면 세로로 로우면 가로로 꽉 채움
                  Expanded(child: Image.asset('image/dice$leftDice.png')),
                  SizedBox(
                    width: 20,
                  ),
                  Expanded(child: Image.asset('image/dice$rightDice.png')),
                ],
              ),
            ),
            SizedBox(
              height: 60,
            ),
            ButtonTheme(
              child: ElevatedButton.icon(
                style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.orangeAccent,
                    minimumSize: Size(100, 60)),
                onPressed: () {
                  setState(() {
                    leftDice = Random().nextInt(6)+1;
                    rightDice = Random().nextInt(6)+1;
                  });
                  showToast("Left dice: {$leftDice}, Right dice: {$rightDice}");
                },
                icon: Icon(Icons.play_arrow),
                label: Text("Next"),
              ),
            )
          ],
        ),
      ),
    );
  }
}

void showToast(String message){
  Fluttertoast.showToast(msg:message,
    backgroundColor: Colors.white,
    toastLength: Toast.LENGTH_SHORT,
    gravity: ToastGravity.BOTTOM,
  );
}

 

+ Recent posts