Flutter : 画像の選択

Flutter + Firebase でアプリ作成のためのパーツあつめ。

画像選択のパッケージ、image_picker を試す。

https://pub.dev/packages/image_picker

のだが、AndroidX互換性問題に遭遇し難儀したが、何とか解決

1.Flutter

1.1 pubspec.yaml (/) にimage_pickerを追記

dependencies:
    :
  image_picker: ^0.6.1+8

1.2 second.dart

画面遷移で起動した画面に、画像選択し、画像表示するウィジェットを追加する (関係ないコードは除外)

ウィジェットのルートにScaffoldを使用したままだと、写真を選択したときにサイズがはみ出ると、下図のように、はみで多分に黒と黄色の車線がはいって表示され、以下のようなエラーログが吐かれる。

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following assertion was thrown during layout:
A RenderFlex overflowed by 236 pixels on the bottom.

flutter_pick_image_err

スクロールできるようにする必要があるようなので、以下のサンプルソースに合わせて、スクロールビューの中に入れる。

https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html

import 'dart:convert';
import 'dart:io';

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


class SecondRoute extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _SecondRoute();
  }
}
class _SecondRoute extends State<SecondRoute>{
  Image _image = Image.network('https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg');

  Future _handleImagePick(BuildContext context) async {
    var imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
    var image = Image.file(imageFile);
    setState(() {
      _image = image;
    });
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints viewportConstraints) {
        return SingleChildScrollView(
          child: ConstrainedBox(
            constraints: BoxConstraints(
              minHeight: viewportConstraints.maxHeight,
            ),
            child: IntrinsicHeight(
              child: Column(
                children: <Widget>[
                  Container(
                    // A fixed-height child.
                    color: const Color.fromARGB(255, 255, 255, 255),
                    height: 120.0,
                  ),
                  Expanded(
                    // A flexible child that will grow to fit the viewport but
                    // still be at least as big as necessary to fit its contents.
                    child: Container(
                      color: const Color(0xffffffff),
                      height: 240.0,
                      constraints: BoxConstraints(
                        minWidth: viewportConstraints.maxWidth,
                        minHeight: double.infinity
                      ),
                      child: Column(
                        children: <Widget>[
                          RaisedButton(
                            onPressed: () {
                              _handleImagePick(context);
                            },
                            child: Text('Image Pick'),
                          ),
                          _image,
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }

}

2.Android

画像の初期表示には、Flutter Imageクラスのサンプル画像を表示。

flutter_pick_image01

「Image Pick」ボタン押下でギャラリーから画像を選択できる。

var imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);

のImageSource を、ImageSource.camera に変更することで、カメラが起動する!

flutter_pick_image02

選択すると、Image コンポーネントに選択された画像がロードされる!

flutter_pick_image03

3.iOS

Androidに対応して、少し変更する必要がある。

info.plist(/ios/Runner) に以下を追記。それぞれの機能(key)を利用するときに、目的(string)を表示しユーザーに許可を求める。

<dict>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>What purpose to use</string>
    <key>NSCameraUsageDescription</key>
    <string>What purpose to use</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>What purpose to use</string>
    <key>CFBundleDevelopmentRegion</key>
    :
</dict>

エミュレーターで実行。Androidと同様に表示された。

flutter_pick_image_ios01

「Image Pick」ボタンで、ユーザーに確認。OK押下。

flutter_pick_image_ios02

ギャラリー?が表示されるので、画像を選択。

flutter_pick_image_ios03

選択した画像が、表示された!

flutter_pick_image_ios04

AndroidX対応で、結構はまったが、行けそうか!?

iOSについても勉強する必要あるな。