Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ChangeNotifierの実装(メインページ) #16

Merged
merged 21 commits into from
Jul 15, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions lib/di.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import 'package:chat_flutter/providers/user.dart';
import 'package:chat_flutter/ui/pages/main/home/home_controller.dart';
import 'package:chat_flutter/ui/pages/main/main_controller.dart';
import 'package:chat_flutter/ui/pages/main/profile/profile_controller.dart';
import 'package:chat_flutter/ui/pages/main/talk/talk_controller.dart';
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';

Expand All @@ -7,5 +11,17 @@ List<SingleChildWidget> get providers {
ChangeNotifierProvider<UserProvider>(
create: (_) => UserProvider(),
),
ChangeNotifierProvider<MainController>(
create: (_) => MainController(),
),
ChangeNotifierProvider<HomeController>(
create: (_) => HomeController(),
),
ChangeNotifierProvider<TalkController>(
create: (_) => TalkController(),
),
ChangeNotifierProvider<ProfileController>(
create: (_) => ProfileController(),
),
];
}
6 changes: 3 additions & 3 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import 'package:provider/provider.dart';
import 'package:chat_flutter/di.dart';
import 'package:chat_flutter/ui/pages/add_friend.dart';
import 'package:chat_flutter/ui/pages/create_group.dart';
import 'package:chat_flutter/ui/pages/main.dart';
import 'package:chat_flutter/ui/pages/profile_edit.dart';
import 'package:chat_flutter/ui/pages/profile.dart';
import 'package:chat_flutter/ui/pages/main/main.dart';
import 'package:chat_flutter/ui/pages/main/profile/profile_edit.dart';
import 'package:chat_flutter/ui/pages/main/profile/profile.dart';
import 'package:chat_flutter/ui/pages/room.dart';
import 'package:chat_flutter/ui/pages/sign_in.dart';
import 'package:chat_flutter/ui/pages/sign_up.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/providers/user.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:chat_flutter/services/user.dart';
import 'package:flutter/material.dart';

import '../model/user.dart';
import 'package:chat_flutter/model/user.dart';

class UserProvider with ChangeNotifier {
UserProvider() {
Expand Down
89 changes: 31 additions & 58 deletions lib/ui/pages/home.dart → lib/ui/pages/main/home/home.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,46 @@
import 'package:chat_flutter/config/app_space.dart';
import 'package:chat_flutter/ui/molecules/home/list_tile.dart';
import 'package:chat_flutter/ui/pages/main/home/home_controller.dart';
import 'package:flutter/material.dart';
import 'package:chat_flutter/model/user.dart';
import 'package:chat_flutter/model/group.dart';

import 'package:chat_flutter/config/app_text_size.dart';
import 'package:provider/provider.dart';

class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _homeController = Provider.of<HomeController>(context);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build配下に listen: true でProvideすると、HomeControllerに変更があるたびに、このcontext(HomePage)が丸ごと再描画されてしまうので、あんまり良くないかもです!
ここでは

  • listen: false で定義しておいて、単発呼び出しではこれを使ってあげる
  • 変更を監視したいプロパティの場合はちょっとめんどうくさいけど、 Provider.of<HomeController>(context, listen: true).hoge みたいに逐一取得してあげる感じですかね

前に記事書いてみたので参考にしてみてください!
https://qiita.com/hohohoris/items/8aecf6a99b278d67d13b

retrun  ChangeNotifierProvider<HomeController>(
      create: (_) => HomeController(),
      child: SingleChildScrollView(
         // 略
    )

とすると `main.dart` でMultiProviderしなくてもpageごとにできると思います!

return SingleChildScrollView(
child: Column(
children: <Widget>[
HomePageListTile(
name: 'name',
imgUrl: 'https://dot.asahi.com/S2000/upload/2019100100055_1.jpg',
isMe: true,
FutureBuilder(
future: _homeController.getMeById('test'),
builder: (BuildContext context, AsyncSnapshot<User> snapshot) {
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
switch (snapshot.connectionState) {
case ConnectionState.waiting: // データの取得まち
return Center(
child: CircularProgressIndicator(),
);

default:
if (snapshot.hasData) {
return HomePageListTile(
name: snapshot.data.name,
imgUrl: snapshot.data.imgUrl,
isMe: true,
);
} else {
return Center(
child: Text("該当するユーザーがいません"),
);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return Center(
child: Text("該当するユーザーがいません"),
);
return const Center(
child: Text("該当するユーザーがいません"),
);

のように書けますかね?
constをつけると、コンパイル時に確定できるので、パフォーマンスが上がります
以下参考

Use const widgets where possible. (This is equivalent to caching a widget and re-using it.)

https://medium.com/flutter-jp/state-performance-7a5f67d62edd

}
}
},
),
Container(
constraints: BoxConstraints(
Expand Down Expand Up @@ -46,7 +71,7 @@ class HomePage extends StatelessWidget {
),
),
FutureBuilder(
future: _getGroupList(),
future: _homeController.getGroupList(),
builder: (
BuildContext context,
AsyncSnapshot<List<Group>> snapshot,
Expand Down Expand Up @@ -120,7 +145,7 @@ class HomePage extends StatelessWidget {
),
),
FutureBuilder(
future: _getFriendList(),
future: _homeController.getFriendList(),
builder: (
BuildContext context,
AsyncSnapshot<List<User>> snapshot,
Expand Down Expand Up @@ -185,56 +210,4 @@ class HomePage extends StatelessWidget {
),
);
}

Future<List<Group>> _getGroupList() async {
final List<Group> groupList = [
Group(
name: "Sport",
imgUrl: "https://prtimes.jp/i/24101/70/resize/d24101-70-320114-0.jpg",
),
Group(
name: "Study",
imgUrl: "https://prtimes.jp/i/24101/70/resize/d24101-70-320114-0.jpg",
),
Group(
name: "Hobby",
imgUrl: "https://prtimes.jp/i/24101/70/resize/d24101-70-320114-0.jpg",
),
];

await Future.delayed(Duration(seconds: 1));
return await Future.value(groupList);
}

Future<List<User>> _getFriendList() async {
final List<User> friendList = [
User(
name: "Alex",
imgUrl:
"https://pbs.twimg.com/profile_images/581025665727655936/9CnwZZ6j.jpg",
isMe: false,
),
User(
name: "Alex2(笑)",
imgUrl:
"https://pbs.twimg.com/profile_images/581025665727655936/9CnwZZ6j.jpg",
isMe: false,
),
User(
name: "Jack",
imgUrl:
"https://pbs.twimg.com/profile_images/581025665727655936/9CnwZZ6j.jpg",
isMe: false,
),
User(
name: "Brian",
imgUrl:
"https://pbs.twimg.com/profile_images/581025665727655936/9CnwZZ6j.jpg",
isMe: false,
),
];

await Future.delayed(Duration(seconds: 3));
return await Future.value(friendList);
}
}
66 changes: 66 additions & 0 deletions lib/ui/pages/main/home/home_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'package:chat_flutter/model/group.dart';
import 'package:chat_flutter/model/user.dart';
import 'package:flutter/material.dart';

class HomeController with ChangeNotifier{
HomeController();

Future<User> getMeById(String userId) async {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

基本Controllerのメソッドは戻り値を Future<void> にして、 Controllerのプロパティで Userを持ってあげます。
するとFuture型を処理せずともUserという型でWidgetに通知できるからです。
具体的には、

Suggested change
Future<User> getMeById(String userId) async {
User user;
Future<void> getMeById(String userId) async {
await Future.delayed(Duration(seconds: 1));
user = User(name: "test", imgUrl: "https://dot.asahi.com/S2000/upload/2019100100055_1.jpg");
notifyListeners()

User user = User(name: "test", imgUrl: "https://dot.asahi.com/S2000/upload/2019100100055_1.jpg");

await Future.delayed(Duration(seconds: 1));
return await Future.value(user);
}

Future<List<Group>> getGroupList() async {
final List<Group> groupList = [
Group(
name: "Sport",
imgUrl: "https://prtimes.jp/i/24101/70/resize/d24101-70-320114-0.jpg",
),
Group(
name: "Study",
imgUrl: "https://prtimes.jp/i/24101/70/resize/d24101-70-320114-0.jpg",
),
Group(
name: "Hobby",
imgUrl: "https://prtimes.jp/i/24101/70/resize/d24101-70-320114-0.jpg",
),
];

await Future.delayed(Duration(seconds: 1));
return await Future.value(groupList);
}

Future<List<User>> getFriendList() async {
final List<User> friendList = [
User(
name: "Alex",
imgUrl:
"https://pbs.twimg.com/profile_images/581025665727655936/9CnwZZ6j.jpg",
isMe: false,
),
User(
name: "Alex2(笑)",
imgUrl:
"https://pbs.twimg.com/profile_images/581025665727655936/9CnwZZ6j.jpg",
isMe: false,
),
User(
name: "Jack",
imgUrl:
"https://pbs.twimg.com/profile_images/581025665727655936/9CnwZZ6j.jpg",
isMe: false,
),
User(
name: "Brian",
imgUrl:
"https://pbs.twimg.com/profile_images/581025665727655936/9CnwZZ6j.jpg",
isMe: false,
),
];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここら辺はMockを作成しても良さそうですね 🙆‍♂️ (チームでの話し合いを聞いていなかったのでもし見当違いのことを言っていたらすいません 🙇 )


await Future.delayed(Duration(seconds: 3));
return await Future.value(friendList);
}
}
42 changes: 17 additions & 25 deletions lib/ui/pages/main.dart → lib/ui/pages/main/main.dart
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
import 'package:chat_flutter/ui/molecules/home/app_bar.dart';
import 'package:chat_flutter/ui/molecules/profile/app_bar.dart';
import 'package:chat_flutter/ui/molecules/talk/app_bar.dart';
import 'package:chat_flutter/ui/pages/home.dart';
import 'package:chat_flutter/ui/pages/profile.dart';
import 'package:chat_flutter/ui/pages/talk.dart';
import 'package:chat_flutter/ui/pages/main/home/home.dart';
import 'package:chat_flutter/ui/pages/main/main_controller.dart';
import 'package:chat_flutter/ui/pages/main/profile/profile.dart';
import 'package:chat_flutter/ui/pages/main/talk/talk.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class MainPage extends StatefulWidget {
@override
_MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
int _currentIndex = 0;
void changePage(int index) {
setState(
() => _currentIndex = index,
);
}

class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _mainController = Provider.of<MainController>(context);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メソッド内で定義されたものはそもそもメソッド内のスコープでしか使用できないのでprivateにする必要はなさそうですね 👌

final List appBarList = [
HomePageAppBar(),
TalkPageAppBar(),
Expand All @@ -40,20 +31,21 @@ class _MainPageState extends State<MainPage> {
];

return Scaffold(
appBar: appBarList[_currentIndex],
backgroundColor: backgroundColor[_currentIndex],
bottomNavigationBar: bottomNavigation(),
body: pages[_currentIndex],
appBar: appBarList[_mainController.currentIndex],
backgroundColor: backgroundColor[_mainController.currentIndex],
bottomNavigationBar: bottomNavigation(context),
body: pages[_mainController.currentIndex],
);
}

Widget bottomNavigation() {
Widget bottomNavigation(BuildContext context) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

逆にここは他のファイルから参照されていなければprivateにして良さそうです 👌

final _mainController = Provider.of<MainController>(context);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

上に同じくprivateにする必要はなさそうですね 👌

return BottomNavigationBar(
backgroundColor: Colors.white,
type: BottomNavigationBarType.fixed,
showSelectedLabels: false,
showUnselectedLabels: false,
currentIndex: _currentIndex,
currentIndex: _mainController.currentIndex,
items: [
BottomNavigationBarItem(
icon: Icon(
Expand All @@ -80,9 +72,9 @@ class _MainPageState extends State<MainPage> {
),
),
],
onTap: (index) => setState(
() => _currentIndex = index,
),
onTap: (index){
_mainController.changePage(index);
}
);
}
}
13 changes: 13 additions & 0 deletions lib/ui/pages/main/main_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:flutter/material.dart';

class MainController with ChangeNotifier{
int currentIndex;
MainController(){
currentIndex = 0;
}

void changePage(int index){
currentIndex = index;
notifyListeners();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:chat_flutter/config/app_space.dart';
import 'package:chat_flutter/providers/user.dart';
import 'package:chat_flutter/ui/atoms/profile_image.dart';
import 'package:chat_flutter/ui/pages/main/profile/profile_controller.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

Expand All @@ -12,9 +12,9 @@ class ProfilePage extends StatelessWidget {
const ProfilePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final userProvider = Provider.of<UserProvider>(context);
final _profileController = Provider.of<ProfileController>(context);
return FutureBuilder<User>(
future: userProvider.getUserById("userId"),
future: _profileController.getUserById("userId"),
builder: (BuildContext context, AsyncSnapshot<User> snapshot) {
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
Expand Down
17 changes: 17 additions & 0 deletions lib/ui/pages/main/profile/profile_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
import 'package:chat_flutter/model/user.dart';

class ProfileController with ChangeNotifier{
ProfileController();

Future<User> getUserById(String userId) async {
User user = User(name: "test", imgUrl: "");

await Future.delayed(Duration(seconds: 1));
return await Future.value(user);
}

void changeProfileInfo(){
//Firebaseへの変更通知
}
}
Loading