스터디/Flutter+Dart

Flutter Icon, Asset PNG, SVG, NetworkImage, Gif, Loading...

Dalmangyi 2019. 7. 24.

지난번 Widget 게시글

https://dalgonakit.tistory.com/100

 

Flutter Hello Widget! | Text Example, Button Example

지난 게시글 https://dalgonakit.tistory.com/99 Flutter 프로젝트 만들고 실행하기 | VSCode 지난번 게시글 Flutter 시작하기 | MacOS에서 VSCode로.. 안드로이드와 아이폰은 개발한지도 오래 됬는데.. 최근 회사..

dalgonakit.tistory.com

 

 


 

 

들어가기 전에

Text Widget과 기타 Widget을 써보니 이제 flutter에서 이미지는 어떻게 넣는지 궁금해졌습니다

이미지는 Icon, Asset(Resource)에 있는 Image, Network에 있는 이미지를 알아보겠습니다.

Icon의 경우는 Material을 써봤으니 그 안에 있는 Icon을 사용해보기로 하고, Network 이미지는 어떤 형식으로 불러와지고 최적화 될 수 있게 PlaceHolder는 어떻게 사용하는지 알아보려고 합니다.

 

게시글 내용에서 Package (패키지) 내용이 많이 나옵니다.

아래 링크를 통해 패키지에 대해서 구경하시는것도 괜찮다고 생각됩니다

 

https://medium.com/@changjoopark/%ED%94%8C%EB%9F%AC%ED%84%B0-flutter-%EC%9D%98-pubspec-yaml-ffa40b26296a

 

플러터(Flutter)의 pubspec.yaml

플러터 프로젝트를 새로 만들면 pubspec.yaml 파일을 볼 수 있습니다. Node.js의 package.json과 같은 패키지 의존성 관리 및 프로젝트 정의 등의 역할을 갖습니다.

medium.com

 

 

 

 

 


1. Icon 

import 'package:flutter/material.dart';

void main() {
    runApp(MaterialApp( 
        home: Center(child:
          Icon(
            Icons.add,
            color: Colors.pink,
            size: 30.0,
          )
        ),
    ));
} 

Icon Widget을 사용하면, 아이콘을 띄우는데는 정말 간단합니다. 

 

위 사용된 Icon Widget의 파라매터 설명

  • IconData : 예제에서는 IconData 형식으로 Icons.add를 파라매터로 삽입 했습니다.
  • color : 아이콘을 마스킹 처리하여 설정된 색으로 변경 시켜 줍니다. 
  • size : 아이콘이 차지할 픽셀 사이즈 입니다. 휴대폰 마다 같은 사이즈로 보여줄려면 dp 사이즈를 픽셀로 변환한 후에 대입해줘야 할꺼같습니다.

상하 여백이 잘린 이미지 : 예제 코드를 실행한 화면

 

아이콘 이미지들

아이콘 이미지는 어디서 가져올까요?

우리가 코드 처음에 material package를 import한걸 아시나요? 여기 안에 icon.dart가 포함되어 있습니다

 

Material 아이콘 홈페이지

아이콘이 정말 많이 포함되어 있는데 어떻게 생긴지 몰라서 찾기가 힘들땐 구글의 Material 홈페이지에서 찾아보시면 됩니다

https://material.io/tools/icons

add를 찾아보니 샘플에서 생긴 add랑 똑같이 생겼네요 (당연...)

여기 홈페이지에서는 Material Package를 import하지 않아도 쓸 수 있게 다운로드 기능을 제공하고 있습니다.

 

다운로드시 아이콘의 상세 테마 (Filled, Outlined, Rounded, Tow-Tone, Sharp)를 설정할 수 있고, 

아래에 Selected Icon을 클릭하게 되면 더욱 상세한 설정을 하고 다운로드 할 수 있습니다.

https://material.io/tools/icons 의 아이콘 상세 옵션

아이콘의 메인 색상과 사이즈도 정할 수 있고, 다운로드시 SVG 혹은 PNG 타입으로 선택해서 다운받을 수 있습니다.

 

 

 

 


2. Asset PNG Image

PNG 이미지를 프로젝트에 포함시켜서 읽는 방법은 매우 간단합니다

 

1) 이미지를 구합니다

flutter_logo.png.zip
0.02MB

2) 프로젝트 폴더 최상위에 assets 폴더를 만들어주세요

3) 이미지를 assets폴더에 넣습니다

4) 프로젝트 폴더 최상위에 있는 pubspec.yaml 에 asset정보와 png경로를 추가합니다

flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true
  
  assets:
    - assets/flutter_logo.png

uses-material-design: true 밑에 써주면 됩니다.

🚨주의해야 할 점은 글자 앞에 있는 들여쓰기(탭)을 조심해주세요. yaml 문법에선 들여쓰기를 통해서 포함관계를 나타냅니다.

 

5) Image.asset() 함수를 사용해서 yaml에 등록한 경로를 뿌려주는 Image Widget을 만들 수 있습니다.

import 'package:flutter/material.dart'; 

void main(){
  runApp(
    MaterialApp(
        home: Image.asset('assets/flutter_logo.png')
      )
  );
}

6) 결과 확인

상하 여백이 다 블랙이여서 편집하였습니다.

 

 

 

 


3. Asset SVG Image

Flutter가 지금은 기본적으로 SVG(벡터이미지)를 지원하고 있지 않습니다.

그래서 SVG Package(Library)를 이용해야 합니다

 

1) pubspec.yaml 파일안에 dependencies 안에 'flutter_svg: ^0.13.1' 문구를 추가해 줍니다

dependencies:
  flutter:
    sdk: flutter

  flutter_svg: ^0.13.1
 

🚨여기도 yaml 파일이므로 들여쓰기를 조심 

 

2) 추가후 저장을 하게 되면 packages get 이 동작하면서 'flutter_svg' package를 다운받습니다.

3) 프로젝트의 최상위 폴더에 asset폴더를 만들고 svg파일을 넣기 (자세한건 '2.Asset PNG Image' 를 참고)

flutter_logo.svg.zip
0.00MB

4) pubspec.yaml 파일에 asset 경로 추가하기 

flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true
  
  assets:
    - assets/flutter_logo.svg

🚨여기도 yaml 파일이므로 들여쓰기를 조심 

 

5) package를 import 

import 'package:flutter_svg/flutter_svg.dart'; 

 

6) SvgPicture.asset을 이용해서 SVG파일 불러오기

void main(){
  runApp(
    MaterialApp(
        home: SvgPicture.asset('assets/flutter_logo.svg')
      )
  );
}

 

7) 결과확인

상하 여백이 다 블랙이여서 편집하였습니다.

 

 

 

 

 


4. Network PNG Image

1) 정말 간단하게도 Image.network() 를 이용하면 해결 됩니다

void main(){
  runApp(
    MaterialApp(
        home: Image.network(
          'https://picsum.photos/250?image=9',
        )
      )
  );
}

2) 결과 확인

상하 여백이 다 블랙이여서 편집하였습니다.

+) 심지어 gif 이미지도 잘 동작합니다

void main(){
  runApp(
    MaterialApp(
        home: Image.network(
          'https://media.giphy.com/media/61XRgiopTwXYda9sTX/giphy.gif',
        )
      )
  );
}

에뮬레이터에서 실행한 모습의 gif, 출처 : giphy / thanos frog

+) webp파일을 추후에.......

 

 

 

 


5. Network Image PlaceHolder

네트워크 이미지의 경우 언제 로딩될지 모르는 상태이기 때문에 대체 이미지 (PlaceHolder)를 보여주는 기능을 이용하는것을 추천합니다. 

 

5.1 투명한 이미지를 이용한 FadeIn

1) pubspec.yaml 파일에 transparent_image 패키지 'transparent_image: ^1.0.0' 추가

dependencies:
  flutter:
    sdk: flutter

  transparent_image: ^1.0.0

2) transparent_image 패키지 import

import 'package:transparent_image/transparent_image.dart';

3) FadeInImage.memoryNetwork 함수 사용

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

void main(){
  runApp(
    MaterialApp(
        home: FadeInImage.memoryNetwork(
            placeholder: kTransparentImage,
            image: 'https://picsum.photos/250?image=9',
        )
      )
  );
}

4) 결과 확인

실제 장면을 녹화한 gif

5.2 Asset에 있는 이미지를 이용한 FadeIn

1) Asset 이미지 (png, gif) 파일을 준비합니다 (자세한건 '2.Asset PNG Image' 를 참고)

2) yaml에 dependencies 패키지 추가 없이, 소스코드에 패키지 import 필요가 없습니다

3) FadeInImage.assetNetwork() 함수를 이용해서 placeholder와 network image를 설정합니다

import 'package:flutter/material.dart'; 

void main(){
  runApp(
    MaterialApp(
        home: FadeInImage.assetNetwork(
            placeholder: 'assets/flutter_logo.png',
            image: 'https://picsum.photos/250?image=9',
        )
      )
  );
}

4) 결과 확인

실제 장면을 녹화한 gif. 로딩이 좀 걸립니다.

 

 

 

 

 


6. Network Image Placeholder + Cached

네트워크 이미지를 가져오다보면 로딩이 걸려서 placeholder 처리를 하곤 합니다. 

이전에 이미지를 불러왔을때 캐쉬로 저장해 둔것을 다음번에 이미지를 불러오게 될때 캐쉬된 이미지를 보여주면 더 빨리 로딩될 수 있을 것입니다. 

 

1) pubspec.yaml 에 cached_network_image 패키지 추가 

dependencies:
  flutter:
    sdk: flutter

  cached_network_image: ^1.1.1

 

2) cached_network_image 패키지 import 

import 'package:cached_network_image/cached_network_image.dart';

 

3) CahedNetworkImage() 함수를 사용

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

void main(){
  runApp(
    MaterialApp(
        home: Center(
          child: SizedBox(
            child:CachedNetworkImage(
              placeholder: (context, url) => CircularProgressIndicator(),
              imageUrl: 'https://picsum.photos/250?image=9',
            ), width: 250, height: 250
          )
        )
      )
  );
}

placeholder로 image가 아닌 Indicator도 세팅할 수 있습니다.

Indicator와 이미지는 위치가 정해지지 않을 경우, 사이즈가 정상동작하지 않아서

Center Widget을 추가하고 SizedBox로 감싸놓았습니다 

 

4) 결과 확인

 

실제 장면을 녹화한 gif. 로딩이 너무 빠르네요;;

 

 

 

 

 

 

 

 

 

 


마치며

정말 flutter는 쓰면 쓸수록 간단한거 같습니다.

물론 이런 작은 예제일땐 쉽지만, 프로젝트가 되었을땐 어느 정도나 편할지 모르겠지만 기대가 됩니다

이미지를 써보니 사진첩에서 이미지를 가져오고, 카메라로 찍은 이미지를 가져오는 방법이 궁금해졌습니다.....

 

도움이 되셨다면 좋아요와 댓글 부탁드립니다~

 

 

댓글