Flutter Instagram Clone #6 갤러리에서 사진 불러오기

jakeseo_me·2020년 7월 23일
0

Flutter-Instagram-Clone

목록 보기
6/14

Flutter Instagram Clone #6 갤러리에서 사진 불러오기

원본 강의

https://www.inflearn.com/course/flutter-%EC%9E%85%EB%AC%B8/dashboard

여기서 유료 결제를 해서 듣고있는 강의의 내용을 개인적인 공부 목적으로 지식 위주로 정리해봅니다.

갤러리에서 이미지 불러오는 방법

image_picker 패키지 설치하기

갤러리에서 이미지를 불러오려면 node_module 설치하듯 외부 패키지를 설치하는 것이 편한데, 이미지를 불러오기 위해 image_picker 패키지를 설치할 것이다.

플러터의 패키지 관리 정보는 pubspec.yaml에서 가지고 있는데 여기서 아래와 같은 방식으로 dependencies에 내가 사용할 패키지를 추가할 수 있다. 이번에는 image_picker를 설치한다.

이러한 패키지는 구글에서 찾을 수 있고, pub.dev 사이트에서 찾아볼 수도 있다.

위와 같이 pubspec.yaml에서 패키지 정보를 추가했다면,

안드로이드 스튜디오 우측 상단에 Pub get이라는 글자가 있는데 그걸 클릭하면 실제로 받아와진다.

아래의 메세지 창에 다음과 같은 메세지가 나오면 끝난 것이다.

패키지의 사용법을 알고싶다면, pub.devExample 코너에 잘 나와있다.

패키지를 추가하면 HotReload로는 적용이 안되니 반드시 앱을 재시작해야 한다.

image_picker 샘플 보며 따라하기

강좌에서는 ^5.8.6버전을 사용하였는데, 나는 최신 버전을 이용해보고 싶어서 최신 버전을 설치했다. 현재 최신 버전은 ^0.6.7+4이다.

차이점을 나열해보자면,

  1. ^5.8.6에서는 pickImage라는 메소드를 통하여 이미지를 가져왔는데, 최신버전에서는 getImage라는 메소드를 통하여 이미지를 불러온다.
  2. ^5.8.6에서는 ImagePicker의 static method로서 pickImage를 사용한 반면에 ^0.6.7+4에서는 ImagePicker 객체를 새로 만들어준 뒤에 그 내부에 존재하는 getImage 메소드를 사용했다.
  3. ^5.8.6에서는 반환값이 바로 Future<File>이라 따로 형변환이 필요 없었는데, ^0.6.7+4에서는 Future<PickedFile>이 반환되어, 또 형변환을 해주어야 한다. 그 형변환은 _imagePickedFile일 때, File(_image.path)와 같은 형태로 할 수 있다.

짜증났던 점

MissingPluginException - No implementation found for method pickImage 이러한 오류가 계속 뜨면서 안 됐었는데, 어떻게 해결한 건지는 모르겠지만 그냥 에뮬레이터를 아예 껐다가 다시 켠 후에 실행하니 문제없이 잘 됐다.

결과 소스

import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/basic.dart';
import 'package:image_picker/image_picker.dart';

class CreatePage extends StatefulWidget {
  
  _CreatePageState createState() => _CreatePageState();
}

class _CreatePageState extends State<CreatePage> {
  final textEditingController = TextEditingController();
  PickedFile _image;

  
  void dispose() {
    // 사라질 때 제거
    // TODO: implement dispose
    textEditingController.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _buildAppBar(),
      floatingActionButton: _buildFloatingActionButton(),
      body: _buildBody(),
    );
  }

  Widget _buildAppBar() {
    return AppBar(
      title: Text('새 게시물', style: TextStyle(fontWeight: FontWeight.bold)),
      centerTitle: true,
      actions: <Widget>[
        IconButton(
          icon: Icon(Icons.send),
          onPressed: () {},
        )
      ],
    );
  }

  Widget _buildBody() {
    return SingleChildScrollView(
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(8.0),
            ),
            _image == null ? Text('No Image') : Image.file(File(_image.path)),
            TextField(
              controller: textEditingController,
              decoration: InputDecoration(hintText: '내용을 입력하세요.'),
            )
          ],
        ),
      ),
    );
  }

  Widget _buildFloatingActionButton() {
    return FloatingActionButton(
      child: Icon(Icons.add_a_photo),
      backgroundColor: Colors.blue,
      onPressed: () {
        _getImage();
      },
    );
  }

  Future _getImage() async {
    final pickedImage =
        await ImagePicker().getImage(source: ImageSource.gallery);
    setState(() {
      _image = pickedImage;
    });
  }
}

결과 소스는 위와 같다. 비동기처리 같은 경우에는 ES6이후의 자바스크립트와 흡사하다. 함수의 끝에 async 키워드를 이용할 수 있고, await 키워드로 비동기 동작을 기다릴 수 있다.

그리고 사진을 넣고 내용을 쓰려고 하면 유저 입력용 키보드 UI가 화면의 반을 차지하게돼서 공간이 부족하다는 에러가 뜨는데, 그럴 때는 SingleChildScrollView를 이용하여 화면을 맵핑하면 스크롤바가 생기며 화면공간 부족 에러가 사라진다.

결과

내가 원하는 이미지를 첨부하여 글을 작성할 수 있다. 아직 등록은 안 된다.

profile
대전에 있는 (주) 아이와즈에서 풀스택 웹개발자로 일하고 있는 서진규입니다. 주로 Jake Seo라는 닉네임을 많이 씁니다. Javascript를 좋아합니다.

0개의 댓글