🎩
ボタンのグレーアウトのロジックを考えてみた!
友達に頼まれて作ってみた!
TextFieldに値が入力されないと、ボタンがグレーアウトして押せないロジックをriverpodで考えるようにいわれて、やってみたのですが、結構難しかったですね😅
海外の記事を参考になんとか頑張って作りました!
完成品のサンプルコード
今回参考にしたコードはこちらです。
// 参考にしたコード
class _TempDialogState extends State<TempDialog> {
final TextEditingController _inputController = TextEditingController();
final TextEditingController _inputController2 = TextEditingController();
bool enable = false;
void initState() {
super.initState();
}
void dispose() {
_inputController.dispose();
_inputController2.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Center(
child: Column(children: [
TextField(
controller: _inputController,
onChanged: (data) {
if (_inputController.text.isEmpty ||
_inputController2.text.isEmpty) {
enable = false;
} else {
enable = true;
}
setState(() {});
},
),
TextField(
controller: _inputController2,
onChanged: (data) {
if (_inputController.text.isEmpty ||
_inputController2.text.isEmpty) {
enable = false;
} else {
enable = true;
}
setState(() {});
},
),
ElevatedButton(
onPressed: enable ? () {} : null,
child: Text('${enable}'),
)
])),
),
);
}
}
riverpodを使用して、作ってみたコードです。今回のポイントは、onChange()で、取得した値を判定するようです。
コードが少ないから、フォルダ分けなくてもいいと思ったのですが、分離させたかったので、やってみました。
privider/provider.dart
// TextEditingControllerを使うためのProvider
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// StateProvider は外部から変更が可能なステート(状態)を公開するプロバイダです。
// TextEditingControllerを使うためのProvider
final textProvider = StateProvider.autoDispose((ref) {
// riverpodで使うには、('')が必要
return TextEditingController(text: '');
});
// bool型を使うためのProvider。初期値はfalseにする
final enableProvider = StateProvider.autoDispose((ref) => false);
main.dart
import 'package:button_glay_out/provider/provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
runApp(
const ProviderScope(child: MyApp()),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(home: Home());
}
}
class Home extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
// コードの書き方が変わったのか、[(.state).state]と外と中に.stateを
// 書かないといけない!
// 2回目の.stateは、使う時に呼び出して使う。
// controllerProviderは大丈夫みたい?
final controllerProvider = ref.watch(textProvider.state);
// bool型のProviderを呼び出す!
final boolProvider = ref.watch(enableProvider.state);
return Scaffold(
appBar: AppBar(title: const Text('ButtonGrayOut')),
body: Center(
child: Column(
children: [
TextField(
// ここで、finalに格納した、Providerを使う!
controller: controllerProvider.state,
// onChangedを使わないと、if文の判定ができない!
onChanged: (data) {
if (controllerProvider.state.text.isNotEmpty) {
boolProvider.state = false;
} else {
boolProvider.state = true;
}
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'テキストを入力してください!',
),
),
const SizedBox(height: 20),
// 三項演算子でボタンをtrueなら、グレーアウト
// falseなら、ボタンを押せるようにする。
// 文字が入力されれば、ボタンは押せるようになる!
ElevatedButton(
onPressed: boolProvider.state
? null
: () {
// 取得した値をデバッグする
print(controllerProvider.state.text);
},
child: Text('送信'),
),
],
),
),
);
}
}
最後に
ビジネスロジックを考えて作ってみたのですが、成功したのは、今回が初めてかもしれないですね😅
いい勉強になりました。
Discussion