#最も簡単にいいね機能を実装します!
2つの方法を紹介します。お好きな方法で実装してください!
どちらも簡単ですのでご安心を!
※注意
・StatefulWidgetでsetState()を使えば簡単に作れるけど、全体がリビルドされるから画像やテキストが多い画面でリビルドされると不具合に繋がったり、処理がグダつくのでStatefulWidgetは使いません。
・SNSの機能としていいね機能を実装する場合は,この記事だけでは不十分です。
なぜなら、いいねしたことを保存しなければならないから、サーバーサイドと組み合わせる必要があるからです。
####1.flutter_hooksを利用した方法
####2.providerを利用した方法
hooks_riverpod: ^0.14.0+4
provider: ^5.0.0
準備完了。
#1.flutter_hooksを利用した方法
コードを全部のせます!
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class HooksPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("flutter_hooksパターン"),
),
body: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
index.toString() + "番目",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
),
),
FavoriteButton()
],
);
}),
);
}
}
class FavoriteButton extends HookWidget {
@override
Widget build(BuildContext context) {
final favorite = useState<bool>(false);
return IconButton(
onPressed: () =>
(favorite.value) ? favorite.value = false : favorite.value = true,
icon: Icon(
Icons.favorite,
color: (favorite.value) ? Colors.pink : Colors.black12,
),
);
}
}
重要な部分だけ抜粋します。
class FavoriteButton extends HookWidget {
@override
Widget build(BuildContext context) {
final favorite = useState<bool>(false);
return IconButton(
onPressed: () =>
(favorite.value) ? favorite.value = false : favorite.value = true,
icon: Icon(
Icons.favorite,
color: (favorite.value) ? Colors.pink : Colors.black12,
),
);
}
}
favoriteの値が変更されると,内部のnotifyListeners();が実行されてHookWidgetがリビルドされます。
#2.providerを利用した方法
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ProviderPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("providerパターン"),
),
body: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return ChangeNotifierProvider<FavoriteModel>(
create: (_) => FavoriteModel(),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
index.toString() + "番目",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
),
),
Consumer<FavoriteModel>(builder: (context, model, child) {
return IconButton(
onPressed: model.changeColor,
icon: Icon(
Icons.favorite,
color: model.favorite ? Colors.pink : Colors.black12,
),
);
})
],
));
}),
);
}
}
class FavoriteModel extends ChangeNotifier {
bool favorite = false;
void changeColor() {
if (favorite) {
favorite = false;
} else {
favorite = true;
}
notifyListeners();
}
}
各々のListに対して, FavoriteModel()を生成するので、create: (_) => FavoriteModel(),の位置が重要です。ボタンが押されたら、model.chageColorを呼び出されるので、Consumerで囲った部分がリビルドされます。