Google Flutter コラム- 第3回 Mapbox地図とUIの重ね合わせ(1/2)

Google Flutterのコラム第3回・4回では、

mapboxの地図にFlutterUIを重ね合わせてカーナビのような画面を作成していきます。

実際の作成内容をお伝えする前に、

第3回ではGoogle Flutterの基本をおさらいしてみようと思います。

Flutter環境構築がまだの方は、

「Google Flutter コラム- 第1 回 Google Flutter を 導入してみた」で詳しく解説しています。

ぜひ環境構築をして、本文で紹介しているサンプルコードなどを動かしてみてください。

Flutter User Interface(UI) 基本概念

Flutterレイアウト

01. Widget

WidgetとはFlutterフレームワークの中心となるクラス層です。

UIなどFlutterで使用される画面要素のほぼ全てが、このクラスを継承しています。

UI部品のWidgetは大きく2つに分類されます。

状態を持たず静的なUI部品として扱われる「StatelessWidget」と、

アプリの操作や処理により、見た目などの状態が動的に変化する「StatefulWidget」です。

StatelessWidgetの代表は、Textクラス、Iconクラスなどです。

どちらのクラスも状態を持たず描画後、見た目が変わることはありません。

StatefulWidgetの代表は、ElevatedButtonクラス、AnimatedAlignクラスなどです。

ElevatedButtonクラスは基本的なボタン機能を提供します。

ボタン押下などで見た目が動的に変化します。

AnimatedAlignクラスはアニメーション機能を提供します。

様々なWidgetに対して決められたアニメーションを実施します。

自作のFlutterアプリ画面は主にStatefulWidgetを継承して作成します。

画面更新(テキストやUIの切り替え)などで、状態に応じて見た目を変えることが多いためです。

その他たくさんのWidgetがGoogle Flutterでは提供されています。

詳しくは公式のWidget catalogで使いたいWidgetを見つけてみてください。

02. 画面レイアウト概要

Flutterの画面レイアウトはWidgetを重ね合わせるように作成していきます。

レイアウトのベースとなるクラスはContainer、Column/Rowなどです。

Containerクラスは子Widgetのカスタマイズを行います。

カスタマイズする子Widgetを決めるchildプロパティや,背景色を決めるcolorプロパティを持ちます。

様々なWidgetを一纏めにして管理するのに適しており、

上位のWidget(親Widget)として使用することが多いです。

Column/Rowクラスは複数の子Widgetを画面に配置します。

配置する子Widgetを決めるchildrenプロパティや、配置順序を決めるcrossAxisAlignmentプロパティを持ちます。

childrenに配置したいWidgetを設定することで、

複数のWidgetを簡単に整列させることができます。

【Container & Column/Row サンプル】 ※Runボタンを押すことでサンプルを実行できます
              
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() {
  debugPaintSizeEnabled = true;
  runApp(MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
          body: Center(
              child: Container(
                  color: Colors.white,
                  width: 300,
                  height: 300,
                  child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        Row(
                          children: [
                            Container(
                              child: const Text("Row Child1"),
                              color: Colors.blue,
                              width: 100,
                              height: 100,
                            ),
                            Container(
                              child: const Text("Row Child2"),
                              color: Colors.red,
                              width: 100,
                              height: 100,
                            ),
                          ],
                        ),
                        Column(children: [
                          Container(
                            child: const Text("Column Child1"),
                            color: Colors.yellow,
                            width: 100,
                            height: 100,
                          ),
                          Container(
                            child: const Text("Column Child2"),
                            color: Colors.green,
                            width: 100,
                            height: 100,
                          ),
                          Container(
                            child: const Text("Column Child3"),
                            color: Colors.orange,
                            width: 100,
                            height: 100,
                          )
                        ])
                      ]))))));
}
            
サンプルは最背面のContainerから最前面のTextに向けて枝が伸びるTree構造になっています。

Flutterの開発ではこのようなWidgetの重りをイメージすることで、

最終的な画面レイアウトが理解しやすくなります。

Android Studioでは、Flutter Inspector → Details Treeで詳細を確認することもできます。

マテリアルデザイン

01. マテリアルデザインとは

(出典:https://material.io/design/foundation-overview)

「マテリアルデザインは、ユーザーが接する画面にマテリアル(物質)、

 メタファーの概念を用いて一貫性のある世界をつくりつつ、ユーザーの操作を補助するものである」
 (出典:ウィキペディア マテリアルデザイン)

レイアウト、ナビゲーション、色、モーションなど、アプリデザインの原則が細かくまとめられており、

Androidのアプリデザインでは広く普及している概念です。

詳しくはGoogleのマテリアルデザイン公式サイトを参照してみてください。

02. MaterialApp

マテリアルデザインの公式サイトをご覧になられた方は、

アプリへ取り入れるのが難しそうだと思われたかもしれません。

Google Flutterでは標準機能として、

マテリアルデザインをサポートしたUIなどのライブラリ(material library)が提供されており、
手軽にマテリアルデザインに準拠したアプリを作成することが可能です。

Flutterアプリにマテリアルデザインを取り入れるのに、

最も簡単な方法は、MaterialAppクラスを使用して画面を作成することです。

そのためには、runApp()の際にMaterialAppクラスを設定します。

これだけで、マテリアルデザインに準拠したWidgetを使って自作の画面を作ることができます。

【MaterialApp サンプル】 ※Runボタンを押すことでサンプルを実行できます

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'MaterialApp Sample',
    debugShowCheckedModeBanner: false,
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: const MyAppScreen(title: 'MaterialApp Sample'),
  ));
}

@immutable
class MyAppScreen extends StatefulWidget {
  const MyAppScreen({Key? key, required this.title}) : super(key: key);
  final String title;

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

class _MyAppScreenState extends State<MyAppScreen> {
  int _counter = 0;
  int _selectedIndex = 0;
  final List<String> _myStr = <String>[
    "Welcome to the Google Flutter column",
    "NSK",
    "Enjoy the column"
  ];
  Text _myText = const Text("Welcome to the Google Flutter column");

  final List<MaterialColor> _myColorList = <MaterialColor>[
    Colors.blue,
    Colors.red,
    Colors.green
  ];
  MaterialColor _myColor = Colors.blue;

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
      _myText = Text(_myStr[index]);
    });
  }

  void _incrementCounter() {
    setState(() {
      _myColor = _myColorList[_counter];
      _counter = (_counter + 1) % _myColorList.length;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
                child: Center(child: _myText),
                color: _myColor,
                width: 300,
                height: 100),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Color change',
        child: const Icon(Icons.brush),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            label: 'Company',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            label: 'Study',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}
            

サンプルのように特別な処理を作らなくても、

シンプルなUIが普段使うスマホアプリのように配置されます。
また、ボタンのON/OFFの状態に合わせて見た目も変えることができます。

まとめ

今回はGoogle Flutterの基本を振り返りました。

基本を押さえれば、Flutterでアプリを作るのはとても簡単です。

サンプルコードは、ほんの触りの機能しか作っていないので、

今回紹介したコードを改造してみて、Flutterの面白さを体感してみてください。

本格的に開発をする場合は、PCに環境を構築するのが良いですが、

すぐに試したいという方は、DartPadで試してみるのもおすすめです。

次回は、カーナビのような画面の作成内容と、

今回紹介しきれなかった、さまざまなWidgetについても合わせてお伝えします。

○GoogleMap
○mapbox(mapbox_gl:0.11.0)
○GoogleMap
○mapbox(mapbox_gl:0.12.0)
○GoogleMap
○mapbox(mapbox_gl:0.12.0)
○GoogleMap
○mapbox(mapbox_gl:0.12.0)
○GoogleMap
○mapbox(mapbox_gl:0.12.0)
○GoogleMap(Night Theme)
○mapbox(mapbox_gl:0.12.0、DARK)

お問い合わせ

名古屋本社

東京本社

【受付時間】9:00~18:00

pagetop

お客様のお悩み承ります。