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);
}

 

다시 로또프로그램 만들기

 

코드 리팩토링이란?

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

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

 

참고: 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,
  );
}

 

 

플러터 버전업이 되면서 ScaffoldMessenger.of(context)를 사용함

onPressed: (){ //버튼을 눌렀을때
  ScaffoldMessenger.of(context).showSnackBar(
    //SnackBar 구현하는법 context는 위에 BuildContext에 있는 객체를 그대로 가져오면 됨.
      SnackBar(
        content: Text('Like a new Snack bar!'), //snack bar의 내용. icon, button같은것도 가능하다.
        duration: Duration(seconds: 5), //올라와있는 시간
        action: SnackBarAction( //추가로 작업을 넣기. 버튼넣기라 생각하면 편하다.
          label: 'Undo', //버튼이름
          onPressed: (){}, //버튼 눌렀을때.
        ),
      )
  );
}

 

출처: https://learncom1234.tistory.com/23

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

이미지 처리  (0) 2023.01.17
focus  (0) 2023.01.17

 

확인할 것

- setState사용법 확인

- FloatingActionButton은 여러개 표현할 때 Stack으로 표현

 

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  void _decrementCounter(){
    setState(() {
      _counter--;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),

      ),
      floatingActionButton: Stack(
        children:[
          Align(
            alignment: Alignment(
              Alignment.center.x-0.15, Alignment.center.y + 0.35
            ),
            child: FloatingActionButton(
              onPressed: _incrementCounter,
              tooltip: 'Increment',
              child: const Icon(Icons.add),
            ),
          ),
          Align(
            alignment: Alignment(
                Alignment.center.x+0.4, Alignment.center.y + 0.35
            ),
            child: FloatingActionButton(
              onPressed: _decrementCounter,
              tooltip: 'Decrement',
              child: const Icon(Icons.remove),
            )
          )
        ],
      )
    );
  }
}

 

상속 문법(생성자에 유의해서 보길)

class Person{
  String? name;
  int? money;
  Person(this.name, this.money){}

  void status(){
    print("이름: $name , 골드: $money");
  }
}

class Hero extends Person{
  int? hp;
  int? mp;
  Hero(this.hp, this.mp, super.name, super.money);
  //생성자에서 중괄호 안에 내용이 없을 경우 생략해도 됨
  //단 생략할 경우 위 예시처럼 세미콜론 필수
  @override
  void status(){
    print("이름: $name , 골드: $money");
    print("hp: $hp , gold: $mp");
  }
}

class Magician extends Hero{
  String? skill;
  int? damage;
  Magician(this.skill, this.damage, super.hp, super.mp, super.name, super.money){}

  void magic(){
    print("Magic: $skill ,Dagmage: $damage!!");
  }
}


void main(){
  Person p1 = Person("Tim", 100);
  p1.status();
  Hero h1 = Hero(1,2,"Tim",100);
  h1.status();
  Magician m1 = Magician("Meteor", 999, 10,30,"Harry", 999);
  m1.status();
  m1.magic();
  m1.magic();
  m1.magic();
  m1.magic();
}

 

아래는 옛날 방식

class DialPhone{
  int? year;
  DialPhone(){
    print('이 전화기는 다이얼을 돌려서 전화를 겁니다.');
  }

  void whenCame(){
    print("1889년 발명");
  }
}

class ButtonPhone extends DialPhone{
  ButtonPhone(){
    print("이 전화기는 버튼을 눌러서 전화를 겁니다.");
  }

  @override
  void whenCame(){
    print("1963년 발명");
  }
}

class SmartPhone extends ButtonPhone{
  String? manufacturer;
  String? model;

  SmartPhone(String manufacturer, String model, int year){
    this.manufacturer = manufacturer;
    this.model = model;
    this.year = year;

    print("이 전화기는 터치를 해서 전화를 겁니다.");
  }

  @override
  void whenCame(){
    print("1993년 처음 등장");
  }
}

void main(){
  SmartPhone s1 = SmartPhone("제조사:삼성", "모델명:겔럭시 S20", 2020);
  print(s1.manufacturer.toString() + s1.model.toString() + s1.year.toString());

  s1.whenCame();
}

 

+ Recent posts