【Flutter/Dart】画像を表示する(Container、BoxDecoration)

目次

概要

Flutterで画像を表示する時は単にファイルを追加して、そのパスを読み込めば良いというわけではない。ファイルに追加する以外にも色々な手順が必要だ。
ファイルパスだけではないので、今回はその点を記載していく。

ソースコード

ディレクトリ構造

まずは使用する画像をFlutterプロジェクトへ追加しよう。
ドラッグ&ドロップで追加できる。

pubspec.yaml

以下のassetsに画像を格納してるディレクトリパスを書き込む。

flutter:
  assets:
    - images/

コマンド実行

pubspec.yamlと同じ階層へ移動して以下のコマンドを実行する。

$ flutter pub upgrade

アプリ実行部分

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

import 'Basic/BasicView.dart';


void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),
        useMaterial3: true,
      ),
      home: const BasicView(title: 'Flutter Demo Home Page'),
    );
  }
}

View表示部分

import 'package:flutter/material.dart';

class BasicView extends StatefulWidget {
  const BasicView({super.key, required this.title});
  final String title;

  @override
  State<BasicView> createState() => _BasicViewState();
}

class _BasicViewState extends State<BasicView> {
  var imageContainer = Container(
      width: 120,
      height: 180,
      decoration: BoxDecoration(
          color: Colors.indigoAccent,
          image: DecorationImage(
            image: AssetImage('images/spade_1.png'),
            fit: BoxFit.contain,
          )
      ));

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            imageContainer
          ],
        ),
      ),
    );
  }
}

スクリーンショット

詳細

画像を表示する上で必要になるのは以下の部分だ。

var imageContainer = Container(
      width: 120,
      height: 180,
      decoration: BoxDecoration(
          color: Colors.indigoAccent,
          image: DecorationImage(
            image: AssetImage('images/spade_1.png'),
            fit: BoxFit.contain,
          )
      ));

二つに分かれているので順を追って説明していこう。

Container

まずはContainerだ。これは、とりあえずUIを表示するためのViewを表示するものだ。
設定値には以下のようなものがある。

項目名内容
child表示するUIを設定する
color背景色を設定する
alignmentどのあたりに表示するか
Alignment(0, 0)で中央、Alignment(-1.0, -1.0)で左上、
Alignment(1.0, 1.0)で右下に表示する
margin外側の余白
padding内側の余白
width / height幅、高さ
decorationBoxDecorationを設定する(詳しくは後述)
この項目を設定した場合、color(背景色)は
BoxDecorationで設定しないとエラーが出る

今回は幅を「120」、高さ「180」に設定している。
画像の表示部分はdecorationの部分だ。これはまた新しくオブジェクトを使用するため、続いて書いていく。
ちなみに、ChildはTextを入れたりもできるし、縦並びに配置するColumnや横並びに配置するRowsも設定できる。
複数のUIをひとまとまりにしておきたいときに使われることが多いだろう。

BoxDecoration

グラデーションを行ったり、境界線の設定をしたりと、幅広く対応ができる。
しかし、今回のように画像を表示するのだったら以下の二つで十分だ。

項目名内容
color背景色
※Containerで設定するとエラーが発生する
image画像のファイルパス
fit画像の表示方法

image

imageは以下のように設定する。
「画像のファイルパス」はプロジェクトファイルの階層が基準となっているようだ。

image: AssetImage('/* 画像のファイルパス */')

今回は「’images/spade_1.png’」と設定している。

fit

fitは以下のように設定する。

fit: BoxFit./* 設定値 */
設定値内容
fillContainerの幅と高さに合わせて表示する
縦横比は崩れる
contain縦横比を維持しながらContainerの領域に収まるサイズにする
cover縦横比を維持しながらContainerの領域を完全に覆えるサイズにする
fitWidth縦横比を維持しながらContainerの幅と同じサイズにする
fitHeight縦横比を維持しながらContainerの高さと同じサイズにする
none取得した画像のまま表示する
scaleDown縦横比を維持しながらContainerに収まるサイズに縮小する。拡大はしない。

今回の場合は背景色を青色に、その領域に収まるようにサイズを調整して「images/spade_1.png」の画像を表示している。
その証拠に、Containerの背景色の青色が上下に少し見えているのがわかるだろう。
そう、縦横比を維持しながら画像が収まるように画像のサイズを調整しているから、少しだけ上下に余白ができているのだ。

参考ページ