LoginSignup
5
8

More than 3 years have passed since last update.

Flutterで画像を選択して表示させるまでの流れ

Posted at

掲題の通り説明させていただきます。
また、今回はimage_pickerというパッケージを使用して
アカウント作成画面にて、プロフィール画像を選択するという構成でいきます。

image_pickerパッケージを使用する初動

image_pickerの概要は、以下サイトから学びました。
https://pub.dev/packages/image_picker

iOS版のみ、対応すべきこと

プロジェクトのルート/ios/Runner/Info.plistのファイルに下記を追記いたします。

<key>NSPhotoLibraryUsageDescription</key>
<string>このアプリはフォトライブラリにアクセスする必要があります</string>
<key>NSCameraUsageDescription</key>
<string>このアプリはカメラにファイルを追加する必要があります</string>
<key>NSMicrophoneUsageDescription</key>
<string>このアプリでは、マイクのフォトライブラリにファイルを追加する必要があります</string>

上記は、作成しているアプリが以下3点にアクセスする際の説明書きをしています。

  • 写真のライブラリ
  • カメラ
  • マイク

実際に画像を選択して、表示させるまでのWidgetを作成する

まずは、上掲で挙げたimage_pickerパッケージをインポートします。

image_pickerをインポート

'dart:io'も必要なので、インポートしておきます。

import 'dart:io';

import 'package:image_picker/image_picker.dart';

画像を選択できるボタンを作成

最後あたりの条件文であるif (_pickedFile != null)を記述しておかないと、
画像ライブラリの選択画面で「キャンセル」を押した際にエラーになってしまうので、きちんと記載しておきます。

  ...

  File _image;
  final _picker = ImagePicker();

  ...

                child: FlatButton(
                  onPressed: () => _getImageFromGallery(),
                  child: const Text(
                    '写真を選ぶ',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      color: Color(0xffffffff),
                      fontWeight: FontWeight.w400,
                      fontSize: 15,
                      height: 1.2,
                    ),
                  ),
                ),

  ...


  Future _getImageFromGallery() async {
    final _pickedFile = await _picker.getImage(source: ImageSource.gallery);

    setState(() {
      if (_pickedFile != null) {
        _image = File(_pickedFile.path);
      }
    });
  }

  ...

画像を表示させる

ここでは、画像がないときにはグレーの枠を表示させて、
画像を選択したら、実際に選択した画像を表示させようとしております。

  ...


              Container(
                width: 150,
                height: 150,
                margin: const EdgeInsets.only(top: 90),
                child: _displaySelectionImageOrGrayImage()
              ),

  ...

  Widget _displaySelectionImageOrGrayImage() {
    if (_image == null) {
      return Container(
        decoration: BoxDecoration(
          color: const Color(0xffdfdfdf),
          border: Border.all(
            width: 2,
            color: const Color(0xff000000),
          ),
          borderRadius: BorderRadius.circular(75),
        ),
      );
    } else {
      return Container(
        decoration: BoxDecoration(
          border: Border.all(
            width: 2,
            color: const Color(0xff000000),
          ),
          borderRadius: BorderRadius.circular(75),
        ),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(75),
          child: Image.file(
            _image,
            fit: BoxFit.fill,
          ),
        ),
      );
    }
  }

  ...

全体のソースコード

import 'dart:io';

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

class RegisterProfile extends StatefulWidget {
  const RegisterProfile({Key key}) : super(key: key);

  @override
  _RegisterProfileState createState() => _RegisterProfileState();
}

class _RegisterProfileState extends State {
  File _image;
  final _picker = ImagePicker();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Container(
                alignment: Alignment.topLeft,
                margin: const EdgeInsets.only(top: 81, left: 35, right: 35),
                child: const Text(
                  '最後に、\nプロフィール写真を設定しましょう!',
                  textAlign: TextAlign.left,
                  style: TextStyle(
                    fontWeight: FontWeight.w700,
                    fontSize: 24,
                  ),
                ),
              ),
              Container(
                width: 150,
                height: 150,
                margin: const EdgeInsets.only(top: 90),
                child: _displaySelectionImageOrGrayImage()
              ),
              Container(
                width: 144,
                height: 50,
                margin: const EdgeInsets.only(top: 47),
                decoration: BoxDecoration(
                  color: const Color(0xfffa4269),
                  border: Border.all(
                    width: 2,
                    color: const Color(0xff000000),
                  ),
                  borderRadius: BorderRadius.circular(15),
                ),
                child: FlatButton(
                  onPressed: () => _getImageFromGallery(),
                  child: const Text(
                    '写真を選ぶ',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      color: Color(0xffffffff),
                      fontWeight: FontWeight.w400,
                      fontSize: 15,
                      height: 1.2,
                    ),
                  ),
                ),
              ),
            ],
          ),
          Container(
            child: _displayInSelectedImage()
          )
        ],
      ),
    );
  }

  Widget _displaySelectionImageOrGrayImage() {
    if (_image == null) {
      return Container(
        decoration: BoxDecoration(
          color: const Color(0xffdfdfdf),
          border: Border.all(
            width: 2,
            color: const Color(0xff000000),
          ),
          borderRadius: BorderRadius.circular(75),
        ),
      );
    } else {
      return Container(
        decoration: BoxDecoration(
          border: Border.all(
            width: 2,
            color: const Color(0xff000000),
          ),
          borderRadius: BorderRadius.circular(75),
        ),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(75),
          child: Image.file(
            _image,
            fit: BoxFit.fill,
          ),
        ),
      );
    }
  }

  Widget _displayInSelectedImage() {
    if (_image == null) {
      return Column();
    } else {
      return Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Align(
            alignment: Alignment.topRight,
            child: Container(
              margin: const EdgeInsets.only(bottom: 20, right: 20),
              child: InkWell(
                child: Image.asset(
                  'assets/images/ic_send.png',
                ),
              ),
            ),
          ),
        ],
      );
    }
  }

  Future _getImageFromGallery() async {
    final _pickedFile = await _picker.getImage(source: ImageSource.gallery);

    setState(() {
      if (_pickedFile != null) {
        _image = File(_pickedFile.path);
      }
    });
  }
}

実装した実際の画面

画像を選択していない場合

画像
スクリーンショット 2020-09-29 13.23.11-min.png

画像を選択している場合

画像
スクリーンショット 2020-09-29 13.22.33-min.png

以上で、Flutterで画像を選択して表示させるまでの流れの説明を終了させていただきます。

5
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8