먼저 Radio<TYPE>으로 라디오 버튼을 만들어준다.

 

각 라디오가 서로 그룹임을 알려주려면 하나의 인스턴스를 서로 바라보고 있으면 된다.

int number = 0;

@override
Widget build(BuildContext context) {
  return Column(
    children: [
      Radio<int> (
        value: 0,
        groupValue: number,
      ),
      
      Radio<int> (
        value: 1,
        groupValue: number,
      )
    ],
  )
}

 

 

value는 각 라디오가 가지고 있는 고유 값을 뜻하며, 라디오 버튼을 클릭했을 때 onChanged함수를 통해서 값이 전달된다.

 

 

색상

activeColor를 넣어주어야 isChecked와 기본 색상이다.

 

 

 

https://api.flutter.dev/flutter/material/Radio-class.html

 

Radio class - material library - Dart API

A Material Design radio button. Used to select between a number of mutually exclusive values. When one radio button in a group is selected, the other radio buttons in the group cease to be selected. The values are of type T, the type parameter of the Radio

api.flutter.dev

 

 

Hello Flutter Worldwide.

Today I introduce one of the indie flutter packages.

It is name `flutter_logcat`

 

This package will be incredibly helpful to all of you.
If you make good use of logs, it will make development much more convenient.

 

In Flutter, logs are displayed in the console without any distinguishing colors.
However, by using this package, you can view messages in the console with colors that you define.
Additionally, you can configure it so that logs are hidden in debug mode, and you can also set it to display tags, file paths, and timestamps.

 

 

Usage is very simple!

 

Try it!

 

 

https://pub.dev/packages/flutter_logcat

 

flutter_logcat | Flutter package

You can view messages in the console with colors that you define. Also set it to display tags, file paths, and timestamps

pub.dev

 

랜덤하게 숫자를 받아야 한다. 그것을 '난수'라고 부른다.

1부터 10까지 랜덤하게 숫자를 받고 싶은 경우 Random을 사용한다.

 

Import

import 'dart:math';

 

Create Instance

var random = Random();

// 1 ~ 10
int result = random.nextInt(10) + 1;

 

+1을 해주지 않으면 0부터 9까지 숫자를 갖게 된다.

 

 

double형태로 받고 싶은 경우 (0.0 ~ 1.0)

double resultDouble = random.nextDouble();

 

 

Boolean형태로 받고 싶은 경우

bool resultBool = random.nextBool();

 

 

Color로 받고 싶은 경우

// Random from 'dart:math'
Color currentColor = Color((Random().nextDouble() * 0xFFFFFF).toInt());

try ~ catch란? "예방", "방어"의 의미로 볼 수 있다.

 

코드를 작성하다보면 정말 다양한 경우의 수를 만나게 된다.

내가 받아야하는 결과값이 모호한 경우 try ~ catch문을 사용한다.

 

기본 사용법

  try {
    int result = int.parse("Occur Error!");
    print("result:$result");
  } catch (e, stackTrace) {
    print("Error:$e");
  }

 

String타입을 int타입으로 변환(형변환)하려는 코드이다.

에러메시지는 다음과 같이 표출된다.

Error:FormatException: Occur Error!

 

 

에러 추적 하는법

catch안에는 사실 두 개의 파라메터가 존재하다.

e만 있는 것이 아닌 stackTrace도 정의해주면 에러가 어떻게 발생되었는지 그 과정을 볼 수 있다.

  try {
    int result = int.parse("Occur Error!");
    print("result:$result");
  } catch (e, stackTrace) {
    print("Error:$e");
    print("StackTrace:$stackTrace");
  }

 

 

 

'on'키워드 사용

Error의 메시지를 보면 FormatException이 발생한 것을 알 수 있다.

상황에 따라서 여러 예외상황이 발생했을때 다르게 분기처리를 해주어야 하는 경우도 있을 것이다.

그런 경우를 위해 'on' 키워드를 사용해서 예외를 분리한다.

  try {
    int result = int.parse("Occur Error!");
  } on FormatException {
    print("Implement.. FormatException");
  } catch (e) {
    print("Error:$e");
  }
}

 

if문처럼 조건이 맞으면 다음 catch문은 읽지 않기 때문에 상황에따라 적절하게 구현하면 될 것이다.

추가로 on FormatException이라고 분리해준뒤 catch문을 사용해서 어떠한 에러인지 왜 발생했는지 추적할 수 있다.

  try {
    int result = int.parse("Occur Error!");
  } on FormatException catch(e, stackTrace){
    print("Implement.. FormatException.. Error:$e");
  } catch (e) {
    print("Error:$e");
  }

 

 

finally키워드

try ~ catch문을 사용한 이후 어떠한 작업이 이루어져도 무조건적으로 실행해주는 동작을 뜻한다.

에러가 발생해도 무조건 실행해주는 동작, 이라고 이해하면 쉽다.(당연히 정상적인 동작이 되어도 실행해준다)

  try {
    int result = int.parse("Occur Error!");
  } on FormatException catch(e, stackTrace){
    print("Implement.. FormatException.. Error:$e");
  } catch (e) {
    print("Error:$e");
  } finally{
    print("Finally Exit Casting Operate String to Integer..");
  }

 

 

rethrow 고급 문법

try ~ catch내부에 또다른 try ~ catch가 있는 경우 rethrow키워드를 사용해서 상위 try ~ catch문에 Exception을 전달하는 것이다. 예외를 발생하는 것을 상위 try ~ catch문으로 다시 던지는 것이라고 보면 된다.

 

File - New - New Flutter Project - Package

 

pubspec.yaml 설정

name: [라이브러리 이름]
description: [설명]
version: 1.0.1 //버전
homepage: [홈페이지 주소]
repository: [코드 저장소 주소]

 

 

example 폴더 생성

- 생성시 pub.dev에서 example란에 표시됨

flutter create example

 

- android, ios만 생성하고 싶은 경우

flutter create --platforms android,ios -a kotlin -i swift example

 

 

example yaml에서 본인 라이브러리를 사용하는 방법

path: ../ 추가

dev_dependencies:
  flutter_test:
    sdk: flutter

  [라이브러리 이름]:
    path: ../

 

 

코드 정렬

dart format .

 

점검, 확인

flutter pub publish --dry-run

 

올리기

flutter pub publish

 

 


Pub Cache경로 설정

https://dart.dev/tools/pub/cmd/pub-cache

User에 대한 사용자 변수이름 : PUB_CACHE경로 : D:/src/Pub/Cache- 컴퓨터 다시 시작을 해야 잘 적용된다

 

 

특정 OS만 가능하도록 설정

: 아래 사항을 표시하지 않으면 모든 OS에서 사용이 가능함을 뜻함

flutter:
  plugin:
    platforms:
      android: ^2.3.0
      ios: ^3.0.0

 

 

플러그인 

전체 추가 명령

- 아무 플랫폼도 없거나 해당 플랫폼 빌드가 안되면 플러터에서 알려줄 것이다.

flutter create .

 

개별 추가 명령

- android, ios, web, macos, window

flutter create --platforms -android .

 

flutter create --org com.example --template=plugin --platforms=android,ios,linux,macos,windows -a kotlin hello

 

다음과 같이 실행해주어야 '플러그인'이 생성된다.

$ flutter create --org com.donguran --template=plugin --platforms=android,ios -a kotlin -i swift torch

 

 

그리고 gitignore에 다음을 꼭 명시해준다.

* 8 checked-in files are ignored by a `.gitignore`.
  Previous versions of Pub would include those in the published package.

  Consider adjusting your `.gitignore` files to not ignore those files, and if you do not wish to
  publish these files use `.pubignore`. See also dart.dev/go/pubignore

  Files that are checked in while gitignored:

  .idea/.gitignore
  .idea/inspectionProfiles/Project_Default.xml
  .idea/libraries/Dart_SDK.xml
  .idea/libraries/Flutter_Plugins.xml
  .idea/misc.xml
  .idea/modules.xml
  .idea/torch.iml
  .idea/vcs.xml


* D:\donguran\dev\flutter\app\torch\CHANGELOG.md doesn't mention current version (0.1.1).
  Consider updating it with notes on this version prior to publication.
Package validation found the following hint:
* You're about to publish a package that opts into null safety.
  The previous version (0.1.0) isn't opted in.
  See https://dart.dev/null-safety/migration-guide for best practices.

아래는 이미 버전이 있다는 말..

 

패키지 우측 이미지 넣기

ref : bloc패키지 참조

screenshots:
  - description: torchx logo.
    path: screenshots/logo.png

 

 

해당 패키지 admin에서 publisher를 수정할 수 있다.

 

2024-04-23-화 : 패키지 경로를 설정할 때

export: "pacakge:..." 로 시작하지 않고,

내부 경로로 설정해주어도 괜찮다.

 

그리고 'show'키워드를 통해서 사용할 기능만 등록할 수 있다.

 

 

패키지 우측 이미지 넣기

ref : bloc패키지 참조

screenshots:
  - description: torchx logo.
    path: screenshots/logo.png

 

 

해당 패키지 admin에서 publisher를 수정할 수 있다.

 

2024-04-23-화 : 패키지 경로를 설정할 때

export: "pacakge:..." 로 시작하지 않고,

내부 경로로 설정해주어도 괜찮다.

 

그리고 'show'키워드를 통해서 사용할 기능만 등록할 수 있다.

 

 

플러터 폴더명 관례

'src'라는 이름으로 폴더를 만들면 외부에서 접근할 수 없게 된다.

'assets'라는 이름으로 폴더를 만들어야 앱에 번들로 포함되어 빌드된다.

assets하위의 폴더이름은 자유롭게 해도 상관없지만, 

  • json → data
  • 이미지 → images
  • 폰트 → fonts

인터넷 연결이 되어있는지 확인하기위해서 다음 패키지를 사용한다.

 

Add

flutter pub add internet_connection_checker

 

Usage

import 'package:internet_connection_checker/internet_connection_checker.dart';

bool isInternetConnected = await InternetConnectionChecker().hasConnection;

 

 

 

여러번 확인을 하기 위해 'StreamBuilder'를 사용한다.

그리고 10초마다 확인하기위한 Steam함수를 작성한다.

Stream<bool> checkInternetConnectedPeriodically() async* {
  bool isConnect = await checkInternetConnect();
  
  while (!isConnect) {
    yield await checkInternetConnect();
    
    isConenct = await checkInternetConnect();
    await Future.delayed(const Duration(seconds: 10));
  }
  
  yield isConnect;
}
Future<bool> checkInternetConnected() async {
  return await InternetConnectionChecker().hasConnection;
}

 

Use StreamBuilder

@override
Widget build(BuildContext context) {
  stream: checkInternetConnectedPeriodically(),
  builder: (context, AsyncSnapshot<bool> snapshot) {
    if (snapshot.data == true) {
      return Home();
    } else {
      return LoadingProgressbar();
    }
  }
}

Flutter에서 Android의 Fragment처럼 동작되는 위젯을 구현해보았다.

만들 예제는 하나의 기본 화면이 Container안에 있고 추가적으로 다른 위젯을 대체시키고, 뒤로가기가 가능하여 앞의 위젯이 다시 표출되도록 만들것

 

우선, Fragment처럼 사용할 위젯들을 담아내는 Container를 하나 만든다.

List<Widget> container = [];

 

(StatefulWidget으로 setState함수로 UI를 갱신시킬 것이다)

 

 

Android에서 Fragment를 보여주려면 FrameLayout라는 레이아웃안에 넣어 보여준다.

FrameLayout을 '액자'라고 생각하고 Fragment'사진'이라고 생각하면 쉽다.

 

'액자'역할을 해줄 위젯을 만든다. 뒤로가기시 Fragment화면의 동작의 유연함도 고려해야하기 때문에,

'PopScope'위젯으로 전체를 감싸준다.

그리고 FragmentIndexedStack위젯안에 위젯들을 쌓는 형식으로 표현한다.

@override
void initState() {
  super.initState();
  
  container.add(
    SomethingOneWidget()
  );
}

 

 

container리스트 안에 1개이하로 있을때는 PopScope가 정상적으로 동작하고,

2개 이상이 있다는건 Fragment처럼 사용된 위젯들이 IndexedStack안에 쌓여있기 떄문에, 직접 뒤로가기 설정을 해준다.

@override
Widget build(BuildContext context) {
  return PopScope(
    canPop: container.length <= 1,
    onPopInvokedWithResult: (didPop, result) {
      if (!didPop) {
        onBackPressed();
      }
    }
    
    child: ...
  );
}

void onBackPressed() {
  if (container.length > 1) {
    setState(() {
      container.removeLast();
    });
  }
}

 

 

PopScope의 child파라메터 설정

  PopScope(
    ...
    
    child: IndexedStack(
      index: container.length - 1,
      children: container.map((page) {
        return Navigator(
          onGenerateRoute: (settings) {
            return MaterialPageRoute(builder: (context) => page);
          }
        );
      }).toList(),
    )
  );

 

 

 

FirebaseCore패키지를 추가해준다.

flutter pub add firebase_core

 

'IPHONEOS_DEPLOYMENT_TARGET' is set to 11.0, but the range of supported deployment target versions is 12.0 to 17.5.99. 

iOS앱을 빌드하는데 계속해서 발생하였다.

일단 XCode에서 뭔가 target을 맞춰주어야 할 것 같다.

 

현재 iOS 12.0에 맞춰져 있다.

로그에서는 현재 11.0으로 맞춰져있다고 하는데 무엇이 문제일까.

 

XCode좌측창 네비게이션 맨우측 메뉴를 클릭하면 자세한 내용을 볼 수 있다.

 

그리고 오류가 알려주는 곳 위치를 들어가니 iOS Deployment Target이 iOS 11.0으로 맞춰져있다?

 

Pods의 ResourceTarget에 iOS 11.0으로 되어있다. 12.0으로 맞춰보자.

 

이제부터 무언가 빠졌는지를 제공해주는 에러로그가 표출된다.

PhaseScriptExecution FlutterFire: 라는 로그가 표출된다.

 

flutterfire: command not found: 이것은 파이어베이스 연결시 flutterfire라는 명령어를 실행할 수 없음을 나타내는 것 같다.

파이어베이스 연결부분을 다시 확인해보자

링크 : https://firebase.google.com/docs/flutter/setup?hl=ko&platform=web

 

터미널 창에 다음과 같이 명령한다.

curl -sL https://firebase.tools | bash

 

현재 내 맥에는 firebasetools가 다운로드 되어 있기 때문에 다음 명령어를 권유 받았다.

curl -sL firebase.tools | upgrade=true bash

 

 

FlutterFire설치명령어

dart pub global activate flutterfire_cli

 

FlutterFire환경변수를 설정해주어야 한다.

 

나는 현재 환경변수를 .zshenv파일로 관리하고 있다.

다음 명령을 추가하여 환경변수에 추가해준다.

sudo echo PATH=$PATH:$HOME/.pub-cache/bin > ~/.zshenv

 

그리고 다시 FlutterFire명령어를 수행한다.

 

정상적으로 잘설치되었고,

Xcode로 돌아와서 CleanBuildFolder를 한다.

 

 

다시 빌드 시도.

 

성공..!!

이미지를 입힌 버튼이 필요했다.

대표적인 구글, 네이버, 카카오 간편 로그인이다.

 

하지만, 플러터에서는 버튼에 이미지를 입히는 것을 제공하지 않고 있다. (그만한 이유가 있었을까?)

꼭 간편로그인 뿐만 아니라 투명 배경의 이미지를 버튼식으로 만들어서 클릭해야 하는 일이 있다.

 

물론 GestrueDetector, InkWell를 입혀서 표현해주어도 되지만,

Image위젯을 감싼다하더라고 이미지를 클릭한 모션을 제공해주지 않는다.

 

라이브러리 프로젝트 생성

 

무엇을 만들 것인지 정한다 (Project type:)

 

이렇게 만들면 '끝'이지만,

내가 만들 라이브러리(패키지)를 테스트 해보면서 만들어야 완성도가 높아질 것이다.

 

그런 점을 위해서 플러터에서 'example'영역을 제공해준다.

명령어에 다음과 같이 입력한다.

flutter create example .

 

위의 명령어는 모든 플랫폼에 적용가능한 example을 생성해준다.

만약에 특정 OS만 테스트가 가능한 example을 만들고 싶은 경우 다음과 같이 명령한다.

(ex. 안드로이드, iOS, 웹)

flutter create --platforms android,ios,web -a kotlin -i swift example .

 

 

라이브러리 example영역 참조 방법

현재 내가 만든 라이브러리를 example영역에서 참조하고 있지 않기 때문에,

참조를 해주어 테스트를 해볼 수 있다.

 

현재 제작하는 라이브러리 이름은 'picture_button'이다.

다음과 같이 작성한다.

dependencies:
  flutter:
    sdk: flutter
  
  [library_name]:
    path: ../

 

 

Pub.dev사이트 업로드

업로드 하기전 검증 명령어

flutter pub publish --dry-run

 

업로드 명령어

flutter pub publish

 

 

이후 'y'를 입력하여 승인 한다.

 

 

+ 추가로 패키지를 올리기전 코드들을 자동으로 정리해주는 명령어를 사용하면 좋다.

dart format ./

 

+ Recent posts