マテリアルデザインのままiOSぽさを出す

image

初めに

FlutterでiOSアプリを作る際、UIに違和感を覚えるときはないでしょうか?

これはFlutterがマテリアルデザインを採用しているためであり、iOSっぽいUIを作るには工夫が必要です。

一応公式でも「CupertinoWidget」というiOS向けのUIにする方法はあるのですが、個人的に使い勝手が悪いと感じたのであまり使いたくありません。

そこで今回はマテリアルデザインのままiOSぽさを出してみようと思います。

iOSぽさの出ない原因はAppBarとBottomNavigationBar?

マテリアルデザインのAppBarとBottomNavigationBarはクパチーノデザインのものと違い縦幅が大きく、elevationと呼ばれるウィジェットが浮いているように見える影のようなものがついています。

個人的にこの違いがiOSぽさをなくしているように感じるので、この部分をいじってみます。

スクリーンショット

わかりにくいですが、これだけでもiOSぽさが出ています。

以下コード全文です。

import 'package:description/home_page.dart';
import 'package:description/profile.dart';
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Root(),
    );
  }
}

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

  
  State<Root> createState() => _RootState();
}

class _RootState extends State<Root> {
  int _currentIndex = 0;
  final _pageWidgets = [
    //bodyの部分をここで設定
    const HomePage(),
    const Profile(),
  ];

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(43.0),
        child: AppBar(
          title: const Text('タイトル'),
          elevation: 0,
        ),
      ),
      body: _pageWidgets.elementAt(
        _currentIndex,
      ),
      bottomNavigationBar: Container(
        height: 48,
        decoration: const BoxDecoration(
          border: Border(
            top: BorderSide(
              color: Colors.black,
              width: 0.1,
            ),
          ),
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            GestureDetector(
              onTap: () {
                _onItemTapped(0);
              },
              child: const Icon(
                Icons.home,
              ),
            ),
            GestureDetector(
              onTap: () {
                _onItemTapped(1);
              },
              child: const Icon(
                Icons.person,
              ),
            ),
          ],
        ),
      ),
    );
  }

  void _onItemTapped(int index) => setState(() => _currentIndex = index);
}

コード解説

簡単にコードの解説をしていきます。

まずAppBarをPreferredSizeで囲うことで高さの設定ができるようになります。

appBar: PreferredSize(
  preferredSize: const Size.fromHeight(43.0),
  child: AppBar(
    title: const Text('タイトル'),
    elevation: 0,
  ),
),

AppBarは簡単ですが、BottomNavigationBarは少し難しいです。

SizedBoxなどで囲んで高さを調節してもいいですが、端末のサイズが異なったときにエラーが出ることがあります。

なので今回はBottomNavigationBarを使わずにUIを自作しました。

(今回はdecorationでborderを作り、bodyとの境目をわかりやすくしていますがなくても大丈夫です。好みで変更してください。)

bottomNavigationBar: Container(
  height: 48,
  decoration: const BoxDecoration(
    border: Border(
      top: BorderSide(
        color: Colors.black,
        width: 0.1,
      ),
    ),
  ),
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    children: [
      GestureDetector(
        onTap: () {
          _onItemTapped(0);
        },
        child: const Icon(
          Icons.home,
        ),
      ),
      GestureDetector(
        onTap: () {
          _onItemTapped(1);
        },
        child: const Icon(
          Icons.person,
        ),
      ),
    ],
  ),
),

最後に

AppBarとBottomNavigationBarが違うだけでもiOSぽさが出ていい感じになりました。

みなさんもiOSアプリを作るときにUIの参考にしてみてください。

お知らせ

11月5日開催のアプリ開発講座の参加者募集中!!

11月5日開催のアプリ開発講座の参加者募集中!!

11月5日にアプリ開発講座を開催します!会場は岐阜県美濃加茂市のコワーキングスペース「こやぁね」です。興味のある方は是非ご参加ください!

Read More
可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More

お知らせ

11月5日開催のアプリ開発講座の参加者募集中!!

11月5日開催のアプリ開発講座の参加者募集中!!

11月5日にアプリ開発講座を開催します!会場は岐阜県美濃加茂市のコワーキングスペース「こやぁね」です。興味のある方は是非ご参加ください!

Read More
可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More