見出し画像

Flutterでnote公式アプリのクローンを作る

いつも使わせてもらっているnote公式アプリのクローンを作成します。

なおこの記事は有料にさせていただきます。
もしご興味いただけたら購入の方よろしくお願いします。

なお、このチュートリアルでわからないことなどがあればTwitterの方からご連絡お願いいたします。


過去にこんな記事を書いております。こちらは無料ですのでこちらもどうぞ


完成品

完成品はこちらになります。今回はiOSの方になります。(評判がよければAndroid版もやります)


前提

前提としてFlutterの開発環境を作成しておきましょう。

上の記事は英語ですが、頑張って読んでいただいて環境構築していただけたらと思います。

サーバーサイドの開発環境を作るより圧倒的に楽です。

プロジェクト作成

プロジェクトを作成したら、色々コメントが書かれたプログラムが書かれていますが無駄なので今回は消してしまいましょう。

画面の真ん中に「Hello World」って表示します。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
          primaryColor: Colors.white
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("ホーム"),
      ),
      body: new Center(
        child: Text("Hello World"),
      ),
    );
  }
}

テーマカラーの適用

最初にテーマカラーを設定しましょう。

noteで使われている緑のカラーコードはおそらく「#27AD8B」ですのでこの色をこのアプリのベースカラーとしてます。

MyAppクラスのThemeDataの属性を修正します。

class MyApp extends StatelessWidget {

  final noteColor = const Color(0xFF27AD8B);

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        brightness: Brightness.light,
          primaryColor: noteColor,
      ),
      home: new MyHomePage(),
    );
  }
}

これでベースのテーマカラーが設定できました。色を指定しなければ基本的にこの色が当てはめられます。


下タブの実装

_MyHomePageStateの中にbottomNavigationBar属性に下タブのレイアウトを当てはめていきます。

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("ホーム"),
      ),
      body: new Center(
        child: Text("Hello World"),
      ),
      bottomNavigationBar: BottomNavigationBar(
          currentIndex: 0,
          type: BottomNavigationBarType.fixed,
          items: [
            BottomNavigationBarItem(
              icon: new Icon(Icons.home,),
              title: new Text('ホーム'),
            ),
            BottomNavigationBarItem(
              icon: new Icon(Icons.search),
              title: new Text('さがす'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.add),
              title: Text('つくる'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.notifications),
              title: Text('おしらせ'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              title: Text('アカウント'),
            ),
          ]
      ),
    );
  }
}

bottomNavigationBar属性にBottomNavigationBarクラスを設定することによって下タブが作られます。作るボタンのアイコンないので、別のものに代替えています。独自のアイコンを当てはめることも可能ですがここでは説明しません。

アイコンを当てはめたい場合は上記のページが参考になるかと思います。

次にタブをタップするごとにViewを切り替えれるようにしていきます。まずは先に切り替えた先のレイアウトを作成しましょう。

下記の5つのファイルを作成してください

- Home.dart

import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => new _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Home"),
      ),
    );
  }
}

- Search.dart

import 'package:flutter/material.dart';

class Search extends StatefulWidget {
  @override
  _SearchState createState() => new _SearchState();
}

class _SearchState extends State<Search> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Search"),
      ),
    );
  }
}

- Create.dart

import 'package:flutter/material.dart';

class Create extends StatefulWidget {
  @override
  _CreateState createState() => new _CreateState();
}

class _CreateState extends State<Create> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Create"),
      ),
    );
  }
}

- Notification.dart

import 'package:flutter/material.dart';

class NotificationList extends StatefulWidget {
  @override
  _NotificationListState createState() => new _NotificationListState();
}

class _NotificationListState extends State<NotificationList> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Notification"),
      ),
    );
  }
}

- Account.dart

import 'package:flutter/material.dart';

class Account extends StatefulWidget {
  @override
  _AccountState createState() => new _AccountState();
}

class _AccountState extends State<Account> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Account"),
      ),
    );
  }
}

それではここからタブの切り替え機能を実装していきます。

main.dartを編集します。

import 'package:flutter/material.dart';
import 'package:flutter_note_app/Account.dart';
import 'package:flutter_note_app/Create.dart';
import 'package:flutter_note_app/Home.dart';
import 'package:flutter_note_app/Search.dart';
import 'package:flutter_note_app/Notification.dart';

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

class MyApp extends StatelessWidget {

  final noteColor = const Color(0xFF27AD8B);

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        brightness: Brightness.light,
          primaryColor: noteColor,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  int currentIndex = 0;
  List tabLayout = [
    Home(),
    Search(),
    Create(),
    NotificationList(),
    Account()
  ];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("ホーム"),
      ),
      body: tabLayout[currentIndex],
      bottomNavigationBar: BottomNavigationBar(
          currentIndex: currentIndex,
          type: BottomNavigationBarType.fixed,
          onTap: _onTapBottomTab,
          items: [
            BottomNavigationBarItem(
              icon: new Icon(Icons.home,),
              title: new Text('ホーム'),
            ),
            BottomNavigationBarItem(
              icon: new Icon(Icons.search),
              title: new Text('さがす'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.add),
              title: Text('つくる'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.notifications),
              title: Text('おしらせ'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              title: Text('アカウント'),
            ),
          ]
      ),
    );
  }

  _onTapBottomTab(int index) {
    setState(() {
      currentIndex = index;
    });
  }
}


じっくりソースコードを写経してほしいのですが、この実装ではレイアウトをタブによって切り替えています。タブの切り替えを検知してsetStateを呼ぶことでbuildメソッドが呼ばれ、レイアウトを更新している形になります。

タイムライン画面を作成する

いよいよ本格的にレイアウトを作成していきます。

ここから先は

11,726字 / 7画像

¥ 300

投げ銭はいりません。それより無料でできる拡散をしてください!! 感想をツイートしていただけることが一番嬉しいです!!