반응형

[1.이미지(Image)]

[2.컬러(Color)]

[3.텍스트스타일(TextStyle]

 

3. 텍스트 스타일(TextStyle)을 enum으로 관리하는 방법

Text("hello", style: ResTextStyle.t1.bold())

 

 

TextStyle은 flutter ui에서 상당히 많이 사용됩니다.

당연히도 화면에 글지로 표시하여 사용자에게 정보나 의미를 전달해야 되기 때문이죠.(당연한 말이죠? ㅎㅎ)

제가 flutter를 사용하면서 TextStyle을 매번 지정하는 것은 상당히 번거로운 일이었습니다.

코드의 라인수도 늘어날 뿐 아니라 보기도 다른 코드들과 섞이면 흔히 말하는 시인성(코드의 리더빌리티, Readability) 가 떨어지게 되서 불편합니다.

또 코딩하다 text style을 지정할때 잠깐 머뭇거리면서 끈김 현상이 발생합니다(제 머리가요..)

 

TextField(
        controller: controller,
        readOnly: readOnly??false,
        minLines: 1,
        maxLines: 7,
        decoration: InputDecoration(
            contentPadding: EdgeInsets.symmetric(vertical: W(75)),
            filled: true, fillColor: Color.fromRGBO(100,120,100,1.0),
            border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(W(60)), borderSide: BorderSide.none),
            prefixIcon: icon,
            hintText: hintText,
            hintStyle: TextStyle(color: Color.fromRGBO(25,20,25,1), fontSize: 65, fontWeight: FontWeight.w500)),
    );

저는 이런점들을 좀 줄여보고자 몇가지 고민을 했었는데요.

일단 어플리케이션에 사용하는 폰트크기를 미리 정의하는 것이었습니다.

 

class ResFonts{
static cosnt int t1 = 65;
static cosnt int t2 = 58;
static cosnt int t3 = 48;
static const int m1= 24;
static const int m2= 18; 
static const int m3= 16; 
static const int m4= 10; 

 

이런 식으로 정의해서 사용했죠.

또 getTextStyle() 같은 함수를 만들어 사용해보기도 했는데요. 오히려 코딩시에 더 거슬리더군요.

 

최근 enum을 이용해서 간단 textStyle을 만들었는데 의외로 쓸만해서 계속 사용하게 되었습니다.

소개해드리겠습니다.

 

TextStyle 관리하기

제가 사용하는 textstyle 패턴은 아래와 같습니다.

텍스트와 텍스트스타일을 함께 사용하게 되는데 enum을 사용해서 쓰던 ResImage 와 유사하죠.?

Text("hello", style: ResTextStyle.t1.defStyle)

이렇게 사용하면서 상당히 코드의 시인성도 좋아지고 타이핑도 간결해져서 좋더군요.

 

어떻게 만들었는지 한번 보겠습니다.

 

enum을 정의하는 형식은 아래와 같습니다. 폰트의 크기와 기본 weight을 설정하는 형태이죠.

enum ResTextStyle{
  /** fontsize:68 */
  t1(FontWeight.bold, 68),
  /** fontsize:62 */
  t2(FontWeight.bold, 62),
  /** fontsize:58 */
  m1(FontWeight.normal, 58),//58
  /** fontsize:48 */
  m2(FontWeight.normal, 48),

이렇게 하기 위해서는 생성자(constructor)를 다음과 같이 만들어줘야 합니다.

 

final FontWeight fontWeight;
final double fontSize;

const ResTextStyle(this.fontWeight, this.fontSize);

fontWeight와 fontSize를 가지고 생성할 수 있도록 했죠.

다음으로  textStyle을 생성해주는 getter를 하나 만듭니다.

TextStyle get defStyle => TextStyle( fontWeight: fontWeight, fontSize: W(fontSize));

이렇게 하면 위에서 봤던 ResTextStyle.t1.defStyle 이런 방식의 사용이 가능해집니다.

 

저는 처음에 여기까지 해놓고 나서 사용하기 시작했는데, 불편한점들이 몇가지 있었습니다.

- 일단 색상 선택이 불가능하다

- 같은 폰트 크기인데 bold와 normal을 구분하고 싶다.

이런 문제들이 있어서 추가로 getter를 만들려다 함수를 만들게 되었는데,

bold(), normal() 이라는 함수를 추가로 만들게 되었는데, 이러고 나니 상당히 편리한 형태로 사용할수 있고 확장도 가능해졌습니다.

 

TextStyle normal({Color? color, TextOverflow? overflow}) => TextStyle(color: color??ResColors.grayScaleBlack, fontWeight: FontWeight.normal, fontSize: fontSize, overflow: overflow);
TextStyle bold({Color? color, TextOverflow? overflow}) => TextStyle(color: color??ResColors.grayScaleBlack, fontWeight: FontWeight.bold, fontSize:fontSize, overflow: overflow);

실제 사용시에는 다음과 같습니다.

Text("hello", style: ResTextStyle.t1.bold(color:ResColor.gray100)

이런식으로 font크기 + weight + color 가 가능한 형태가 되더군요.

IDE에서 쉽게 검색도 가능한 형태로 말이죠.

 

최종본


enum ResTextStyle{
  /** fontsize:68 */
  t1(FontWeight.bold, 68),
  /** fontsize:62 */
  t2(FontWeight.bold, 62),
  /** fontsize:58 */
  m1(FontWeight.normal, 58),//58
  /** fontsize:48 */
  m2(FontWeight.normal, 48),

  h1(FontWeight.normal, 65), //by ayeong
  ;

  final FontWeight fontWeight;
  final double fontSize;

  const ResTextStyle(this.fontWeight, this.fontSize);

  TextStyle get defStyle => TextStyle( fontWeight: fontWeight, fontSize: fontSize);
  TextStyle normal({Color? color, TextOverflow? overflow}) => TextStyle(color: color??ResColors.grayScaleBlack, fontWeight: FontWeight.normal, fontSize: fontSize, overflow: overflow);
  TextStyle bold({Color? color, TextOverflow? overflow}) => TextStyle(color: color??ResColors.grayScaleBlack, fontWeight: FontWeight.bold, fontSize: fontSize, overflow: overflow);

}

 

이렇게 해서 제가 사용하는 flutter에서 enum을 이용한 resource 관리 방법 3가지 소개해드렸습니다.

 

!! 해피 코딩!!

 

[1.이미지(Image)]

[2.컬러(Color)]

[3.텍스트스타일(TextStyle]

반응형

[1.이미지(Image)] 이미지 관리

[2.컬러(Color)] 색상 관리

[3.텍스트스타일(TextStyle] 텍스트 스타일 관리

2편 컬러 사용법입니다.

이 글을 쓸때 고민이 되었던 부분중 하나가 enum을 사용하여 관리하는 것이 좋을지 기존에 플루터에서 이미 사용하고 있는 방식으로 하는 것이 좋을지 무척 고민이 되었습니다.

이유는 color 부분은 딱히 enum으로 변경한다고 해서 큰 장점이 생긴다고 생각되지 않아서 였는데요. 그래서 간략히 flutter에서 Color 제공하고 있는 방식만 소개하고 넘어갈까 합니다.

 

 

Color color = ResColors.buttonBlue;

이런 방식은 이미 flutter에서도 이렇게 제공하고 있는 부분이 있죠? 이런 방식을 동일하게 사용하는 것입니다.

 

아래와 같이 상수로 컬러를 정의해서 사용하면 됩니다.

abstract class ResColors{

static const Color buttonBlue = Color.fromRGBO(0,0,255,1);

}

이렇게 어플리케이션에서 나만의 color pattern을 사용하는 것입니다.

[예제]

abstract class ResColors{
  static const transparent = Color.fromRGBO(0, 0, 0, 0);
  static const white = Color.fromRGBO(255, 255, 255, 1.0);
  static const black = Color.fromRGBO(0, 0, 0, 1.0);
  static const greenLight_50 = Color.fromRGBO(242, 251, 247, 1.0);
  static const greenLight_100 = Color.fromRGBO(233, 246, 237, 1.0);
  static const greenLight_100F = Color.fromRGBO(212, 229, 212, 1.0); //by karzia
  static const greenLight_500 = Color.fromRGBO(1, 183, 100, 1.0);
  static const greenLight_600 = Color.fromRGBO(25, 161, 77, 1.0);
  static const grayScaleL1 = Color.fromRGBO(247, 247, 247, 1.0);
  static const grayScaleL2 = Color.fromRGBO(244, 244, 244, 1.0);
  static const grayScaleL3 = Color.fromRGBO(238, 239, 241, 1.0);
  static const grayScaleL4 = Color.fromRGBO(237, 237, 237, 1.0);

 

그런데 왜 저는 컬러(Color)를 관리하려고 할까요?

이유는 간단한데요. 협업이 쉽기 때문입니다. 색상표(Color code)가 R,G,B, A 4가지 값을 각각 0~255  만큼 가지고 있는데, 숫자로 되어있습니다.

때문에 소스코드에서 어떤 색상이 어디에 사용되어있는지를 검색하기 쉽지 않습니다.

또 협업을 하게 되는 경우 다른 사람이 작성한 코드에서 컬러값을 찾기는 더 힘들죠.

디자인 가이드가 바뀌는 경우에는 더 많은 작업이 필요해 집니다.

 

예를 들자면, 위에 현재 confirm 버튼으로 사용하고 있는  색상이 RGBO(0,0,255,1) 인데 디자이너가 색상을 좀 옅게 바꾸고 싶어서  confirm 버튼으로 디자인 된곳을 모두 RGBO(100,100, 200,1) 로 변경한다고 합시다.

그러면 개발자들은 RGBO(0,0,255,1)로 된 곳을 모두 찾아서 변경 해야 합니다. 

간혹 빠진 곳이 생기겠죠? 또 개발자중 몇명은 아직 변경 사실을 모르고 있을 수도 있습니다. 그러면 어떤 화면은 적용이 늦어지겠죠.

 

만약 위에 설명드린것 처럼 ResColors와 같이 컬러 테이블을 관리하고 있다면 buttonBlue = Color.fromRGBO(255) 만  Color.fromRGBO(100,100,200,1)로 변경하면 어플리케이션 전체에서 색상을 찾아서 수정할 필요가 없어지겠죠.

 

그래서 보통 어플리케이션에서 사용하는 컬러를 상수나 enum으로 이름을 주고 관리를 하는 편입니다.

이렇게 하면 디자이너와 협업도 쉬워지는데요. 디자이너가 특정 요소의 색상을 바꾸고 싶을때 컬러테이블의 값도 같이 수정 해주고 개발자에게 알려주면, 개발자는 해당 컬러 테이블만 수정 하면 되거든요.

 

 

 

 

 

[1.이미지(Image)] 이미지 관리

[2.컬러(Color)] 색상 관리

[3.텍스트스타일(TextStyle] 텍스트 스타일 관리

반응형

플루터(Flutter)는 Dart 로 UI를 개발하기에 무척 편리한 프래임워크이죠.

실제로 플루터가 나오기 전까지 Dart 언어에 대해서 평가가 그리 좋지 않았지만, 플루터 이후에 평가가 완전히 뒤바뀌었죠.

 

제가 플루터로 어플리케이션을 개발하면서 쌓은 노하우중 하나가 어플리케이션 리소스를 enum으로 관리하는 것인데요.

어떤것인지 소개 드리겠습니다.

 

플루터로 UI를 꾸밀때, 기본적으로 필요한 요소들이 있는데요. 이미지, 컬러, 텍스트스타일, 레이아웃 등이 있죠.

이런것들을 관리하기 위해서 개발자 분들은 다양한 방법을 사용하고 있을텐데요.

 

저는 enum을 활용하는 방법을 소개하고자 합니다.

 

어떻게 enum으로 리소스를 관리하지? 라고 궁금증이 생기신 분들이 있을텐데요.

먼저 제가 왜 enum을 선호하는지 부터 알려드리겠습니다.

 

제가 프로그래밍을 하면서 리소스와 관련되서 종종 격었던 문제들이 있었습니다.

- 텍스트로 리소스를 정의하여 사용하는 경우, 오타로 특정 위치에서만 정상적으로 안나오는 상황

- 플리케이션 리소스를 정의하는 방법이 개발자 간에 서로 달라서 중복된 리소스를 사용하는 경우

- 필요 없다고 생각되는 리소스를 삭제해서 리소스가 안나오는 경우

- 혹시 사용되고 있을까봐 삭제하지 못한 리소스

 

주로 요런 문제들인데요. 아마 이런 문제들은 프로그래밍 언어와 상관없이 코딩을 하다보면 종종 격는 문제입니다.

 

Enum으로 리소스를 관리하게 되면 장점은,

- 컴파일시 (또는 editing시)에 에러를 바로 발견 할수 있다.

- 리소스 사용에 대한 검색이 쉽다.

 

단점은

- 리소스를 위해서 enum을 만들어야 하는 번거로움이 있다.

- 자칫 잘못 디자인 되면 사용이 복잡해진다.

 

저는 예전 경험으로 String을 enum으로 관리하여 유사한 문제점들을 줄였던 적이 있었는데, 이를 활용하여 "어떻게 하면 

코딩이 복잡하지 않고 리소스를 사용할 수 있을까?"에 대해서 고민하여 다음과 같은 방식을 만들게 되었습니다.

 

 

첫번째,

Container(child:Image.asset( ResImages.beast.path, width: 120) )

이미지 리소스를 ResImages.beast.path 이렇게 리소스를 사용하는 방법입니다.

위와 같이 사용하기 위해서는 이미지 리소스를 어떻게 정의할지 고민이 필요한데요. 저는 다음과 같은 방식으로 정의합니다.

enum ResImages{

  addDevice("beast.png"),
  battery("people.png"),
  check("dog.png"),
  dashDevLandS("cat.png"),
  dashDevProbeS("fox.png"),
}

현재는 에러가 발생할 것이고, 

이와같이 정의할 수 있게 하기 위해서는 생성자 (constructor)와 추가적인 내용이 필요합니다.

 

enum ResImages{

:

  final String name;
  const ResImages( this.name);
}

이렇게 하면 string을 enum 정의할때 사용 할 수 있게 됩니다.

다음으로 image path를 얻어오는 getter가 있으면 매우 편리해지겠죠?

 

  String get path => "assets/images/$name";

이렇게 enum에 getter를 추가해 줍니다.

 

이렇게 하면 ResImages.beast.path 로 리소스의 위치를 얻어올 수 있게 됩니다.

요즘 coding 환경( ide)가 좋아져서 ResImages. 까지만 치면 정의된 리소스를 모두 볼수 있으니 더더욱 좋죠.

getter는 필요에 따라서 다양하게 추가할 수 있겠죠? 작은 이미지를 따로 모아놔서 smallPath 를 추가한다던가, 에니메이션을 위해서 프래임을 나눠서 준비했다고 한다면 getFrame(int idx) 같은 식으로 말이죠.

 

최종 완성본은 다음과 같습니다.

enum ResImages{

  addDevice("beast.png"),
  battery("people.png"),
  check("dog.png"),
  dashDevLandS("cat.png"),
  dashDevProbeS("fox.png"),
    ;
  final String name;
  const ResImages( this.name);
  String get path => "assets/images/$name";
 
}

 

 

음, 여기서 고민이 되네요.

이미지, 텍스트 스타일, 컬러를 모두 블로그 한 페이지에 정리할지 아니면 나눠서 정리를 할지.....[10분 딜레이]..

스압을 피하기 위해서 나눠서 정리하기로 했습니다. ^^

 

추가로 관심있으시면 아래 링크 참조 부탁드립니다.

 

[1.이미지(Image)] 이미지 관리

[2.컬러(Color)] 색상 관리

[3.텍스트스타일(TextStyle] 텍스트 스타일 관리

 

반응형

코딩을 하다보면,  사용자 형식의 데이타 구조를 소팅해서 사용해야 하는 경우가 있습니다.

dart 의 List나 map 같은 자료구조에 보면, sort라는 함수가 있는데요. 

이를 활용하면 쉽게 구할 수 있습니다.

 

가장 기본적인 형태는 다음과 같겠죠.

Data라는 class가 있는데 이를 timestamp 기준으로 sorting이 필요하다고 가정하여 sample code를 작성해봤습니다.

class Data{
  int timestamp; // timestamp 로 
  String s;
  Data(this.timestamp,this.s);
  toString(){
    return "$timestamp:$s";
  }
}

List<Data> datas=[
  Data(1,"heee"),
  Data(4,"yyy"),
  Data(2,"kkk"),
  Data(3,"hhph")
];

comp(Data a, Data b){
  return a.timestamp - b.timestamp;
}

void main() {
  datas.sort((a,b)=> comp(a,b));
  
  
  for(final d in datas){
  print("${d.toString()}");  
  }
  
  
}

 

또,

일반적으로 timestamp를 사용할때 DateTime 을 사용하는 경우가 많은데요.

이런 경우 DateTime의 millisecondsSinceEpoch 을 이용하면 쉽게 처리 할 수 있습니다.

DateTime을 사용하지 않고 millisecondsSinceEpoch로 timestamp를 사용하기도 하죠.

class Data{
  DateTime timestamp; // timestamp 로 
  String s;
  Data(this.timestamp,this.s);
  toString(){
    return "$timestamp:$s";
  }
}



List<Data> datas=[
  Data(DateTime.utc(2022,1,25),"heee"),
  Data(DateTime.utc(2022,2,10),"yyy"),
  Data(DateTime.utc(2022,1,5),"kkk"),
  Data(DateTime.utc(2022,4,1),"hhph")
];

comp(Data a, Data b){
  return a.timestamp.millisecondsSinceEpoch - b.timestamp.millisecondsSinceEpoch;
}

void main() {
  datas.sort((a,b)=> comp(a,b));
  
  
  for(final d in datas){
  print("${d.toString()}");  
  }
  
  
}

 

해피 코딩!!

 

반응형

Dart 의 비동기/동기(async/ sync programming) 표현 방법은 상당히 직관적이면서도 편리한 부분들이 많습니다.

효율적인 동작을 위한 코딩을 하려다 보면 필연적으로 async로 코드 작성이 필요로 하게 되죠.

 

아래 간단한 주제를 가지고 한번 얘기 해보고자 합니다.

 

A라는 데이타 목록을 가지고 B라는 과정을 거쳐서 C라는 결과를 도출하고 D라는 데이타 목록으로 저장을 하려고 합니다.
1. A의 각 항목들은 B라는 과정을 거칠때 1~2 초 정도 시간이 걸린다. 
2. B 과정을 입력 A 데이타에 따라 처리 시간이 달라진다.(1초 또는 2초)
3. D에 저장 되는 순서는 A의 순서와 같아야 한다.

일단 A항목들을 순차적으로 처리하게 되면, A의 개수만큼 시간이 늘어나게 됩니다.

따라서 비동기(async)프로그래밍를 고려하게 될 것입니다.

 

위의 상황에 대해서 코딩을 해보면,  가장먼저 다음과 같이 생각해볼 수 있을 것입니다.

A = srcData, B =Future.delayed() , C =  A와 같은 type , D = dstData 라고 합시다.

import 'dart:async';
import 'dart:math';


List<String> srcData=[];
List<String> dstData=[];

init(){
  for( int i = 0;i<24; i++ ){
    srcData.add('mmm_${i}');
  }
}

Future copyToDst(int i){// test를 위해서 1~2초의 랜덤 수행 순서로, src에서 dstData 에 copy 하는 내용.
  return Future.delayed(Duration(seconds: Random().nextInt(2)),(){
    dstData.add(srcData[i]);
    print('src[$i]=>dst');
  });
}



fillDest() async{
  init();
  print("fillDest: length=${srcData.length}");
  for(int s = 0; s<srcData.length ;s++){
    copyToDst(s);
  }
}

void main() async{
 await fillDest();
 await Future.delayed(Duration(seconds: 5));
 print(dstData);
  
}

1초 또는 2초에 처리가 완료 되면, dstData에 저장을 하게 됩니다.

실행 결과는 아래와 같습니다.

기본적인 동작은 하는것 처럼 보입니다.

 

<실행 결과>

fillDest: length=24
src[3]=>dst
src[4]=>dst
src[5]=>dst
src[8]=>dst
src[10]=>dst
src[11]=>dst
src[15]=>dst
src[16]=>dst
src[20]=>dst
src[21]=>dst
src[22]=>dst
src[0]=>dst
src[1]=>dst
src[2]=>dst
src[6]=>dst
src[7]=>dst
src[9]=>dst
src[12]=>dst
src[13]=>dst
src[14]=>dst
src[17]=>dst
src[18]=>dst
src[19]=>dst
src[23]=>dst
[mmm_3, mmm_4, mmm_5, mmm_8, mmm_10, mmm_11, mmm_15, mmm_16, mmm_20, mmm_21, mmm_22, mmm_0, mmm_1, mmm_2, mmm_6, mmm_7, mmm_9, mmm_12, mmm_13, mmm_14, mmm_17, mmm_18, mmm_19, mmm_23]

 

음... 그런데  결과에서 보듯이 "mmm_숫자" 결과의 순서가 srcData의 순서와 맞지 않는 것을 볼수 있습니다.

 

이제 여기서 몇가지 고민을 하게 되겠죠? 가령 "어떻게 순서를 맞출 것인가? " 와 같은 것 말이죠.

대략 한 3가지 방법을 생각해 볼 수 있을것 같네요..

 

첫번째,  copyToDest를  await 으로 처리하는 방법입니다.

  for(int s = 0; s<srcData.length ;s++){
    await copyToDst(s);
  }

 직접 실행해보면, .. 으악... 이런 최악의 수네요..ㅠ_ㅠ 실행시간이 너무 오래걸려요.

 

 

두번째,  map을 이용하는 방법이 있겠네요. 

map을 이용해서 srcData의 순서를 map의  index로 사용하는 방법이죠.

import 'dart:async';
import 'dart:math';


List<String> srcData=[];
Map<int, String> dstData={};

init(){
  for( int i = 0;i<24; i++ ){
    srcData.add('mmm_${i}');
  }
}

Future copyToDst(int i){// test를 위해서 1~2초의 랜덤 수행 순서로, src에서 dstData 에 copy 하는 내용.
  return Future.delayed(Duration(seconds: Random().nextInt(2)),(){
    dstData[i] = srcData[i];
    print('src[$i]=>dst');
  });
}



fillDest() async{
  init();
  print("fillDest: length=${srcData.length}");
  for(int s = 0; s<srcData.length ;s++){
     copyToDst(s);
  }
}

void main() async{
 await fillDest();
 await Future.delayed(Duration(seconds: 5));
 print(dstData);
  
}

 

<실행결과>

fillDest: length=24
src[0]=>dst
src[1]=>dst
src[2]=>dst
src[3]=>dst
src[5]=>dst
src[6]=>dst
src[7]=>dst
src[11]=>dst
src[12]=>dst
src[16]=>dst
src[18]=>dst
src[21]=>dst
src[22]=>dst
src[4]=>dst
src[8]=>dst
src[9]=>dst
src[10]=>dst
src[13]=>dst
src[14]=>dst
src[15]=>dst
src[17]=>dst
src[19]=>dst
src[20]=>dst
src[23]=>dst
{0: mmm_0, 1: mmm_1, 2: mmm_2, 3: mmm_3, 5: mmm_5, 6: mmm_6, 7: mmm_7, 11: mmm_11, 12: mmm_12, 16: mmm_16, 18: mmm_18, 21: mmm_21, 22: mmm_22, 4: mmm_4, 8: mmm_8, 9: mmm_9, 10: mmm_10, 13: mmm_13, 14: mmm_14, 15: mmm_15, 17: mmm_17, 19: mmm_19, 20: mmm_20, 23: mmm_23}

실행결과를 보시면 데이타의 순서는 처리속도에 따라 순서가 달라졌지만, 우리는 map의 index를 사용할 수 있기 때문에 index 순서로 결과를 뽑아볼수 있습니다. ^^ 매우 좋은 결과네요. 

속도도 거의 차이가 없고, 결과도 좋고요.

한가지 걸리는 것은 , dstData를 얻기까지 1~2초가 걸리는데, data가 정상적으로 들어왔는지, 언제 사용해야 하는지가 약간은 애매하네요.

 

 

 

세번째, dstData를 Future List로 변경하는 방법인데요. 

dstData 의 형태를 List<String> 에서 List<Future<String>> 변경하고 copyToDst의 형태도 dstData에 Future<String>을 추가하도록 변경되었습니다.

이렇게 하면 dstData 에는 실행 결과가 들어가는 것이 아니라 실행 명령 순서인 Future<String> 을 저장하는 것을 의도 합니다.

import 'dart:async';
import 'dart:math';


List<String> srcData=[];
List<Future<String>> dstData=[];

init(){
  for( int i = 0;i<24; i++ ){
    srcData.add('mmm_${i}');
  }
}


Future copyToDst2(int i)async{// test를 위해서 1~2초의 랜덤 수행 순서로, src에서 dstData 에 copy 하는 내용.
  return dstData.add(Future<String>.delayed(Duration(seconds: Random().nextInt(2)),(){
    print('src[$i]=>dst');
    return srcData[i];
  }));
}


fillDest() async{
  init();
  print("fillDest: length=${srcData.length}");
  for(int s = 0; s<srcData.length ;s++){
    copyToDst2(s);
  }
}

void main() async{
 await fillDest();
 await Future.delayed(Duration(seconds: 5));
  
  
 List<String> l=[];
 for (var d in dstData){
   l.add(await d);
 }
  
  
 print(l);
  
}

 

추후 Future<String>의 결과를 얻기 위해서는 await dstData[i] 형태로 사용하면 String을 얻어올 수 있게 됩니다.

 

<실행 결과>

fillDest: length=24
src[0]=>dst
src[1]=>dst
src[2]=>dst
src[3]=>dst
src[5]=>dst
src[6]=>dst
src[7]=>dst
src[10]=>dst
src[11]=>dst
src[12]=>dst
src[16]=>dst
src[20]=>dst
src[23]=>dst
src[4]=>dst
src[8]=>dst
src[9]=>dst
src[13]=>dst
src[14]=>dst
src[15]=>dst
src[17]=>dst
src[18]=>dst
src[19]=>dst
src[21]=>dst
src[22]=>dst
[mmm_0, mmm_1, mmm_2, mmm_3, mmm_4, mmm_5, mmm_6, mmm_7, mmm_8, mmm_9, mmm_10, mmm_11, mmm_12, mmm_13, mmm_14, mmm_15, mmm_16, mmm_17, mmm_18, mmm_19, mmm_20, mmm_21, mmm_22, mmm_23]

 

 

추가로, 

map을 사용했을때 " dstData 언제 사용해야 하는지가 약간은 애매하네요." 라고 했던 부분에 대해서 추가로 생각해보자면,

List<Future<String>> 을 사용했던것 처럼, map<int , Future<String>> 으로 사용하게 되면, 필요한 데이타를 사용할때 await을 활용하여 data 결과가 채워지기를 기다릴 수 있겠는데요 ? 

 

아무튼 async 프로그래밍을 다루기에 편리한 언어인 dart 인데 이를 활용 안할 이유가 없을것 같죠? 그렇죠?

 

다들 dart의  async, async* sync, sync* 에 대해서 찾아보시고 알아두시면 즐거운 코딩 생활에 도움이 될것 같습니다.

 

 

+ Recent posts