맥북 에어 m2가 왔다.....

첫 MAC OS인 만큼 적응이 너무 어렵다...

받자마자 뭐부터 만져야 할지도 몰랐다..

 

편하게 바꾸기보단 OS 그 자체를 느껴보고자

순정 상태로 사용해보려고 한다.

 

Flutter 설치를 끝내고 Ios 애뮬을 돌리는데 너무 심장이 떨렸다...

이렇게 빠르다니....

 

맥북은 천천히 익히도록 하고 밀린 Flutter 부터 학습해보자

이번에는 토이프로젝트를 조금씩 완성해보려고한다.

무엇을 할지 모른다면 역시 생각나는 작은것 부터 처리하는게 좋은거같다.

Splash 화면이다. 앱을 처음에 실행하면 나오는 로딩 페이지라고 생각하면 된다.

앱 로고가 아직 없기에 아이폰에 있는 내 이모지를 활용했다.

 

일단 첫번째로 기본 프로젝트를 만들어주자

 

https://pub.dev/packages/flutter_native_splash

위 페이지의 라이브러리를 이용하오니 설치 해주자.

pub get을 해주고

프로젝트 root 디렉토리에 flutter_native_splash.yaml 파일을 만들어주자

 

 

 

 

 

 

 

안에 들어갈 코드는 위 페이지에 나와있다.

코드중 내가 수정한 부분은 단 두줄이다.

백그라운드 컬러 및 로고 이미지 경로

기기의 모드(다크/라이트)에 따라 불러오는 로고를 다르게 설정할 수 있다. 이건 나중에 하도록 하겠다.

 

 

 

 

다음은 main.dart를 수정해보자

import 'package:flutter_native_splash/flutter_native_splash.dart';

를 import 해준뒤

메인 함수에 두줄을 추가한다.

해당 코드를 아래 위젯에 추가해준다.

해당 splash가 3초간 지속되고 첫 페이지로 들어가게 된다.

 

 

 

 

 

 

 

 

 

 

 

 

이로써 Splash 이미지는 구현 완료이다.

참 간단하지만 뭔가 있어보이는? 그런 라이브러리인거같다.

 

다음으로는 get을 이용해 하단 네비게이터바를 구현하여 다중 페이지를 구현하도록할것이다.

 

이전 시간과 비슷하게 ListView.builder를 만들어보자...

 

이번에는 라이브러리 LikeButton을 사용할것이다.

https://pub.dev/packages/like_button

 

like_button | Flutter Package

Like Button is a flutter library that allows you to create a button with animation effects similar to Twitter's heart when you like something.

pub.dev

새로운 프로젝트에 해당 라이브러리를 설치해주자

또 이번에도 이미지를 사용하오니

아래 링크에서 Image 파일을 다운로드 받아 assets 해주자(유튜브 코딩세프님의 자료)

https://github.com/icodingchef/list_page_lecture

 

우선 첫화면으로 뿌려줄 홈을 STF위젯으로 만들어준다.


Animal 클래스를 하나 만들고 생성자 또한 만들어주자.

이름, 위치, 이미지경로 를 갖고있다.

다음 이제 String타입의 이름, 위치, 이미지경로 리스트를 생성해준다.

 static List<String> animalName = [
    'Bear',
    'Camel',
    'Deer',
    'Fox',
    'Kangaroo',
    'Koala',
    'Lion',
    'Tiger'
  ];

  static List<String> animalLocation = [
    'forest and mountain',
    'dessert',
    'forest',
    'snow mountain',
    'Australia',
    'Australia',
    'Africa',
    'Korea'
  ];

  static List<String> animalImagePath = [
    'assets/bear.png',
    'assets/camel.png',
    'assets/deer.png',
    'assets/fox.png',
    'assets/kangaroo.png',
    'assets/koala.png',
    'assets/lion.png',
    'assets/tiger.png'
  ];
Animal 생성자에 리스트 값들을 넣어주기 위해 List.generate 해준다.
animalName의 길이만큼 인덱스를 넘긴다.
body 부분이다.
ListView.builder - Card - ListTile
onTap은 뒷 부분에서 구현하도록 한다.
leading은 맨 왼쪽에 오는 이미지부분이며
title은 animalName
subtitle은 animallocation 을 의미한다.
Navigator을 이용해 해당 페이지로 넘어가게 하자.

 

위와같이 기본 틀 코드를 작성해준뒤 이제 메인페이지에서 데이터를 받아보자

왼쪽과 같이 인자값을 받기위해 작성해주면 오른쪽과 같이 받은 데이터를 뿌려줄수있다.

이제 LikeButton을 구현해보자.

맨 위에 import를 시켜준뒤

 

작성해주면 기본값이 false, 0으로 설정되어
회색과 0으로 표기되고
눌러주면 true로 되며 1로 카운트 된다.

 

날이 쌀쌀하다~

실내는 뜨듯하다..

노곤노곤해지는 환절기이다.

 

얼른 구상중인 개인 프로젝트를 진행하고싶지만 노트북이 많이 버벅이기 때문에,,,

맥북으로 넘어사는대로 진행해야겠다.

 

이번시간에는 ListView.builder이다. 기존 ListView와 다른점은 좀더 많은 양의 데이터를 처리할때 효과적이다.

이번에 만든 앱이다. 크게 appbar와 body-ListView.bulider로 구성되어있다.

우선적으로 ListView에 사용될 이미지를 assets 시켜주자

https://github.com/icodingchef/listview_lecture - 유튜브 코딩셰프님의 자료이다.

 

이미지 assets가 완료되었으면

첫 화면에 뿌려질 페이지를 STF위젯으로 만들어준다.

appbar 구성이며 별거없다.
body 부분과 일체감을 주기위해 배경색과 elevation을 다음과같이 지정했다.
 var titleList = [
    'Dentist',
    'Pharmacist',
    'School teacher',
    'IT manager',
    'Account',
    'Lawyer',
    'Hairdresser',
    'Physician',
    'Web developer',
    'Medical Secretary'
  ];

  var imageList = [
    'assets/1.png',
    'assets/2.png',
    'assets/3.png',
    'assets/4.png',
    'assets/5.png',
    'assets/6.png',
    'assets/7.png',
    'assets/8.png',
    'assets/9.png',
    'assets/10.png'
  ];

  var description = [
    '1.There are different types of careers you can pursue in your life. Which one will it be?',
    '2.There are different types of careers you can pursue in your life. Which one will it be?',
    '3.There are different types of careers you can pursue in your life. Which one will it be?',
    '4.There are different types of careers you can pursue in your life. Which one will it be?',
    '5.There are different types of careers you can pursue in your life. Which one will it be?',
    '6.There are different types of careers you can pursue in your life. Which one will it be?',
    '7.There are different types of careers you can pursue in your life. Which one will it be?',
    '8.There are different types of careers you can pursue in your life. Which one will it be?',
    '9.There are different types of careers you can pursue in your life. Which one will it be?',
    '10.There are different types of careers you can pursue in your life. Which one will it be?'
  ];

ListView에 사용될 데이터들이다. 이미지들의 경로만 다를 수 있고 나머진 복붙하여주면 된다.

클래스내에 작성해주자

body 부분이다.
여기서 return 시켜주는 GestureDetector는 각 타일을 눌렀을때 실행되는 onTap 함수를 위해 사용되었으며
Card를 통해 아이템을 뿌려준다.

Card 부분을 보면 크게 Row로 2개
그리고 2번째 Row에는 Colum으로 3개를 그리고있다.
코드와 같이 Text, SizedBox, Text 위젯 3개로 구성되며
3번째 Text위젯은 사이즈 조절을 위해 SizedBox로 감싸줬다.

이렇게 3가지 위젯을 Padding을 감싸줬다.


showDialog 구현해보자


GestureDetector - onTap 안에 탭하면 
showPopup을 실행하고 인자값을 전달한다.
인자값을 이용하여 Dialog를 리턴시켜주며

 

 

강의를 듣고 따라할때마다 점점 손에 익숙해지는것 같다.

이정도 레벨은 그냥 강의 소리만 들으면서 클론코딩 할 수 있는 정도이다.

 

Getx를 배우고 있는데 노트북이 너무 버거워한다...

조만간 맥북으로 바꾸는것을 목표로 하고 잠시동안

가벼운 프로젝트만 돌리려고한다.

 

이번에는 앱 첫시작에 꼭 들어가는 Onboarding Page를 만들어보려고한다.

앱의 사용설명서 같은것이다.

역시나 외부 라이브러리를 이용할 예정이다.

라이브러리를 설치하는것은 여럿 안내를 했으니 스킵하도록 하겠다.

 

설치가 다됬으면 페이지에 쓰일 이미지를 준비해주자

이미지또한 yaml 파일에서 assets 시켜주자.

 

간단한 트리를 말하자면

OnboardingPage -> main page

이며 역으로 다시 이동도 가능하다.

 

코드와 같이 앱을 실행하면 온보딩 페이지가 뿌려지게

STL 위젯을 만들어준다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

OnBoardingPage이다.

위 라이브러리를 설치하게되면

IntroductionScreen();

을 불러올 수 있다.

 

 

 

 

 

기본적인 틀이다.

pages는 페이지의 리스트이다.

각 페이지를 구현하는 코드는 PageViewModel이며

한개당 하나의 페이지를 그린다.

나는 위젯의 관리를 위해 body 대신 bodywidget을 사용했다.

사진에는 안나와있지만

image: 도 들어가야한다.

 

 

 

 

 

 

decoration 부분은 여럿페이지에 한번에 적용될것이니 따로 분리시켜줬다.

위와같이 PageViewModel 코드를 여러개 작성하면 그만큼 페이지가 나타날것이다.

구성이 완료되었다면.

이 처럼 데코레이션 코드를 작성해주자.

 

 

 

 

 

 

 

 

 

 

 

모든 페이지를 봤다면. 이제 앱의 메인페이지로 진입할때 사용된다. 마지막 페이지에서 보여진다.
다음 페이지로 넘어가기 위한 버튼에 대한 설정이다. 마지막을 제외한 페이지에서 보여진다.
모든 페이지를 보지않고 Skip하는 경우가 많다. 나 역시 그렇다. 이럴때 사용되며 누르면 마지막 페이지로 넘어간다.
페이지 구분 점에 대한 설정 코드들이다. 하나하나 만저보면 어떤 기능인지 감이 올것이다.

추가로...

해당 코드는 페이지 넘김 에니메이션 효과들이다. 

 

 

마지막으로 Main Page에 대한 코드이다.

코드중 pushReplacement를 push 대신 사용한 이유는 죄측상단에 뒤로가기버튼을 안생기게 하기 위함이다.

 

 

안드로이드 스튜디오 하나만 돌려도 cpu 100% 메모리 100%를 차지한다...

이거 참 큰일이다.

핫리로드를 자주쓰지만 자주 메모리땜에 에뮬이 꺼진다...

이럴때마다 에뮬을 다시키고 디버깅을 다시 해줘야하는데

너무 오래걸린다.

프로젝트가 점점 무거워질수록 더욱 이러는거같다.

얼른 맥북하나 장만해야겠다.

오늘 만든 앱이다.

코딩세프 유튜브를 보면된다.

나는 여기에 Amount 와 Count 를 초기화 하는 기능과

getDialog 기능을 추가로 구현했다.

내가 구현한 두가지 기능만 설명 하도록 하겠다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

먼저 CartController 클래스 부분이다.

유튜브에선 addToItem 부분까지만 나와있지만

초기화 시켜주는 것을 구현했다.

 

구현방식은 cartItems는 리스트이기에 .clear()을 통해 리스트를 초기화 했다.

그러면 해당 리스트는 비어있는 상태가 되어 Amount 와 length 모두 0으로 될것이다.

호출 코드이다.

 

 

 

 

 

 

 

 

Get.defaultDialog를 사용하면 되며

기본적으로 title 과 middleText 부분만 작성하면 된다.

내 노트북이 4년 됬더니 배터리 전원선 없이 30분밖에 못쓴다...

알리익스프레스에서 베터리 하나 주문했다.

뒷판을 보니 별나사를 써서.. 쿠팡에서 드라이버 하나 주문했다...

처음 해보는 베터리 교체... 자신있다.

뒷판 뜻고 케이블 분리하고 교체하면 된다고 매우 쉽다고 생각하기 때문이다.

 

이번 시간에는 GetX를 알아보자.

GetX는 상태관리 라이브러리이다. 전세계적으로 가장 많이 쓰이는 라이브러리 이다..

그만큼 말도많은 라이브러리다. 플러터 개발을 너무 쉽게 해준다나 뭐라나..

설명을 들이니 정말 쉽고 편하게 만들어 주는것 같다.

플러터 입문자에겐 악영향을 주는거 같지만 쓰라고 있는건데 안쓸 수 있나..

오늘 만들어볼 앱이다.

빨간 텍스트는 현재 숫자값을 보여준다.

plus button - 현재 숫자값에 1 더해준다.

minus button - 현재 숫자값에 1 뺴준다.

초록색 텍스트는 위 2개 버튼 클릭수이다.

reset button - 현재 숫자값, 클릭수를 0으로 초기화 한다.

 

각 위젯 사이에는 SizedBox 를 넣어줘 여백을 준다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

getX를 설치해보자

맨 아랫줄과 같이 get: 만 해주면 알아서 최신버전을 설치해준다.

이다음 위에 get pub을 눌러준다.

 

그다음 main.dart에 

import 'package:get/get.dart';

를 import 해준다.

 

 

 

다음 프로젝트 lib 폴더에 controller.dart 를 하나 만들어 아래와 같이 코드를 작성해준다.

 

 

Counter 라는 클래스를 만든다.(GetxController를 상속받는,,)

 

 

 

 

 

1 증가, 1 감소, 초기화 이렇게 3가지 구현 해줘야하니 함수 3개를 만들자.

숫자값은 _x로 클릭수는 _y로 구현하겠다.

_x와 _y는 0으로 초기화 한다.

main에서 불러올때는 각각 value, click를 이용하겠다.

 

update(); 는 상태변화를 감지하기 위해 꼭 넣어줘야한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

다음 main에 와서

아랫 코드를 작성하여 생성해준다.

 

 

 

 

 

GetBuilder 이다.

<Counter> 은 Controller에서 만든 클래스 이름을 넣어준다.

builder은 Text를 뿌려준다.

Text안에는 ${controller.value} 가 들어가고

이는 위 Counter() 의 value 값을 가져온다.

 

 

 

 

 

ElevatedButton 이다.

클릭했을때 실행될 함수를 넣는다.

controller는 Counter를 의미하고 Counter의 increment 함수를 실행한다.

controller.dart 의 해당 함수를 보면

_x 는 1 증가

_y 도 1증가

그리고 update(); 를통해 상태 변화를 감지한다.

 

위같은 로직으로 나머지 부분을 구현하면 아래와같다.

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:getxtest/controller.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'GetX Test',
      home: firstPage(),
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {

    Counter controller = Get.put(Counter());

    return Scaffold(
      appBar: AppBar(
        title: Text('GetX Test'),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            GetBuilder<Counter>(
              builder: (_) => Text(
                'Current value is ${controller.value}',
                style: TextStyle(
                    fontSize: 40,
                    color: Colors.red,
                    fontWeight: FontWeight.bold),
              ),
            ),
            SizedBox(x
              height: 20,
            ),
            ElevatedButton(
                onPressed: () {
                  controller.increment();
                },
                child: Text('Plus Button',style: TextStyle(fontSize: 30),)),
            SizedBox(
              height: 20,
            ),
            ElevatedButton(
                onPressed: () {
                  controller.decrement();
                },
                child: Text('Minus Button',style: TextStyle(fontSize: 30),)),
            SizedBox(
              height: 20,
            ),
            GetBuilder<Counter>(
              builder: (_) => Text(
                'Total Counter is ${controller.click}',
                style: TextStyle(
                    fontSize: 40,
                    color: Colors.green,
                    fontWeight: FontWeight.bold),
              ),
            ),
            SizedBox(
              height: 20,
            ),
            ElevatedButton(
                onPressed: () {
                  controller.reset();
                },
                child: Text('Reset Buttom',style: TextStyle(fontSize: 30),)),
          ],
        ),
      ),
    );
  }
}

+ Recent posts