version:flutter_riverpod: ^1.0.3
riverpodを利用して複数のStateを管理しようと考えております。
bool ObscureTextFunction(suffixIcon, ref) { //here
の箇所で悩んでおります。共通化する部分をクラスや関数でまとめた結果、複数のStateを識別することができなくなってしまいました。
つまり、パスワード確認用のsuffixIcon
がタップされた場合、「パスワード」「パスワード確認用」いずれも動作してしまいます。理由は承知しており、どちらがタップされたのかがObscureTextFunction()
上識別できていないからであり、これを識別することは可能でしょうか?
実は同じように識別不能ということでreuse可能な要素が多いにも関わらず、SuffixIconWidget
とSuffixIconWidgetConfirm
をそれぞれ作成したという経緯がございます。クラスを分けさえすれば識別はできてしまうためです。
Dart
1//main.dart 2import 'package:cards/view/textfield.dart'; 3import 'package:flutter/material.dart'; 4import 'package:flutter_riverpod/flutter_riverpod.dart'; 5 6void main() { 7 runApp( 8 ProviderScope( 9 child: MaterialApp( 10 title: 'Cards Demo', 11 home: RegisterWidget(), 12 ), 13 ), 14 ); 15} 16 17class RegisterWidget extends ConsumerWidget { 18 19 Widget build(BuildContext context, WidgetRef ref) { 20 return Scaffold( 21 body: Padding( 22 padding: const EdgeInsetsDirectional.fromSTEB(20, 50, 20, 0), 23 child: Column( 24 children: [ 25 Container( 26 width: double.infinity, 27 height: 50, 28 // color: Colors.grey, 29 alignment: Alignment.topLeft, 30 child: Image.asset('images/logo.png'), 31 ), 32 Container( 33 padding: const EdgeInsetsDirectional.fromSTEB(10, 0, 10, 0), 34 margin: const EdgeInsets.only(top: 30), 35 width: double.infinity, 36 // color: Colors.blue, 37 child: Column( 38 children: [ 39 const Align( 40 alignment: AlignmentDirectional(0, 0), 41 child: TextFieldCustom( 42 labelText: "email", 43 hintText: "メールアドレス", 44 suffixIcon: null, 45 ), 46 ), 47 Align( 48 alignment: const AlignmentDirectional(0, 0), 49 child: TextFieldCustom( 50 labelText: "password", 51 hintText: "パスワード", 52 suffixIcon: SuffixIconWidget()), 53 ), 54 Align( 55 alignment: const AlignmentDirectional(0, 0), 56 child: TextFieldCustom( 57 labelText: "password-confirm", 58 hintText: "パスワード確認用", 59 suffixIcon: SuffixIconWidgetConfirm()), 60 ), 61 ], 62 ), 63 ), 64 ], 65 ), 66 )); 67 } 68} 69
Dart
1//textfield.dart 2import 'package:flutter/material.dart'; 3import 'package:flutter_riverpod/flutter_riverpod.dart'; 4import 'package:font_awesome_flutter/font_awesome_flutter.dart'; 5 6final mask = StateProvider<bool>((ref) => true); 7final maskConfirm = StateProvider<bool>((ref) => true); 8 9class TextFieldCustom extends ConsumerWidget { 10 const TextFieldCustom({required this.labelText, required this.hintText, this.suffixIcon, Key? key}): super(key: key); 11 final String labelText; 12 final String hintText; 13 final Widget? suffixIcon; 14 15 16 17 Widget build(BuildContext context, WidgetRef ref) { 18 return Container( 19 margin: const EdgeInsets.only(bottom: 10), 20 child: TextFormField( 21 style: const TextStyle( 22 fontSize: 13, 23 ), 24 obscureText: ObscureTextFunction(suffixIcon, ref), //here 25 decoration: InputDecoration( 26 labelText: labelText, //** 27 hintText: hintText, //** 28 suffixIcon: suffixIcon, //** 29 labelStyle: const TextStyle( 30 fontSize: 15, 31 color: Color.fromARGB(255, 219, 219, 219), //labelの文字の色 32 ), 33 enabledBorder: OutlineInputBorder( 34 borderRadius: BorderRadius.circular(2), 35 borderSide: const BorderSide( 36 color: Color.fromARGB(255, 219, 219, 219), //outlineの文字の色 37 width: 1.0, 38 ), 39 ), 40 focusedBorder: OutlineInputBorder( 41 borderRadius: BorderRadius.circular(2), 42 borderSide: const BorderSide( 43 color: Color.fromARGB(255, 219, 219, 219), //outline-focusの色 44 width: 1.0, //outlineの太さ 45 )), 46 ), 47 )); 48 } 49} 50 51bool ObscureTextFunction(suffixIcon, ref) { //here 52 //suffixIconがnullではない場合は、パスワードなので、そこで分岐させる 53 print(ref.watch(mask)); 54 if (suffixIcon == null) { 55 return false; 56 } else { 57 final bool isVisible = ref.watch(mask); 58 return isVisible ? false : true; 59 } 60} 61 62class SuffixIconWidget extends ConsumerWidget { 63 64 Widget build(BuildContext context, WidgetRef ref) { 65 final bool isVisible = ref.read(mask); 66 67 return IconButton( 68 icon: Icon(ref.watch(mask) // false 69 ? FontAwesomeIcons.solidEye 70 : FontAwesomeIcons.solidEyeSlash), 71 onPressed: () { 72 ref.read(mask.notifier).update((state) => !isVisible); 73 }, 74 ); 75 } 76} 77 78class SuffixIconWidgetConfirm extends ConsumerWidget { 79 80 Widget build(BuildContext context, WidgetRef ref) { 81 final bool isVisible = ref.read(maskConfirm); 82 83 return IconButton( 84 icon: Icon(ref.watch(maskConfirm) // false 85 ? FontAwesomeIcons.solidEye 86 : FontAwesomeIcons.solidEyeSlash), 87 onPressed: () { 88 ref.read(maskConfirm.notifier).update((state) => !isVisible); 89 }, 90 ); 91 } 92}
調整後コード
Dart
1//main.dart 2//main.dart 3import 'package:cards/view/textfield.dart'; 4import 'package:flutter/material.dart'; 5import 'package:flutter_riverpod/flutter_riverpod.dart'; 6 7void main() { 8 runApp( 9 ProviderScope( 10 child: MaterialApp( 11 title: 'Cards Demo', 12 home: RegisterWidget(), 13 ), 14 ), 15 ); 16} 17 18class RegisterWidget extends ConsumerWidget { 19 20 Widget build(BuildContext context, WidgetRef ref) { 21 return Scaffold( 22 body: Padding( 23 padding: const EdgeInsetsDirectional.fromSTEB(20, 50, 20, 0), 24 child: Column( 25 children: [ 26 Container( 27 width: double.infinity, 28 height: 50, 29 // color: Colors.grey, 30 alignment: Alignment.topLeft, 31 child: Image.asset('images/logo.png'), 32 ), 33 Container( 34 padding: const EdgeInsetsDirectional.fromSTEB(10, 0, 10, 0), 35 margin: const EdgeInsets.only(top: 30), 36 width: double.infinity, 37 // color: Colors.blue, 38 child: Column( 39 children: [ 40 Align( 41 alignment: const AlignmentDirectional(0, 0), 42 child: TextFieldCustom( 43 labelText: "email", 44 hintText: "メールアドレス", 45 ), 46 ), 47 Align( 48 alignment: const AlignmentDirectional(0, 0), 49 child: TextFieldCustom( 50 labelText: "password", 51 hintText: "パスワード", 52 provider: mask, 53 ), 54 ), 55 Align( 56 alignment: const AlignmentDirectional(0, 0), 57 child: TextFieldCustom( 58 labelText: "password-confirm", 59 hintText: "パスワード確認用", 60 provider: maskConfirm, 61 ), 62 ), 63 ], 64 ), 65 ), 66 ], 67 ), 68 )); 69 } 70} 71 72//textfield.dart 73//textfield.dart 74import 'package:flutter/material.dart'; 75import 'package:flutter_riverpod/flutter_riverpod.dart'; 76import 'package:font_awesome_flutter/font_awesome_flutter.dart'; 77 78final mask = StateProvider<bool>((ref) => true); 79final maskConfirm = StateProvider<bool>((ref) => true); 80 81class TextFieldCustom extends ConsumerWidget { 82 TextFieldCustom( 83 {required this.labelText, 84 required this.hintText, 85 this.provider, 86 Key? key}) 87 : super(key: key); 88 final String labelText; 89 final String hintText; 90 final StateProvider<bool>? provider; 91 92 bool obscureTextFunction(WidgetRef ref) { 93 if (provider != null) { 94 final bool isVisible = ref.read(provider!); 95 return isVisible ? true : false; 96 } else { 97 return false; 98 } 99 } 100 101 Widget? suffixIconFuntion(WidgetRef ref) { 102 if (provider != null) { 103 final bool isVisible = ref.read(provider!); 104 return IconButton( 105 icon: Icon(ref.watch(provider!) // false 106 ? FontAwesomeIcons.solidEyeSlash 107 : FontAwesomeIcons.solidEye), 108 onPressed: () { 109 ref.read(provider!.notifier).update((state) => !isVisible); 110 }, 111 ); 112 } else { 113 return null; 114 } 115 } 116 117 118 Widget build(BuildContext context, WidgetRef ref) { 119 if (provider != null) { 120 ref.watch(provider!); 121 } 122 return Container( 123 margin: const EdgeInsets.only(bottom: 10), 124 child: TextFormField( 125 style: const TextStyle( 126 fontSize: 13, 127 ), 128 obscureText: obscureTextFunction(ref), 129 decoration: InputDecoration( 130 labelText: labelText, //** 131 hintText: hintText, //** 132 suffixIcon: suffixIconFuntion(ref), //** 133 labelStyle: const TextStyle( 134 fontSize: 15, 135 color: Color.fromARGB(255, 219, 219, 219), //labelの文字の色 136 ), 137 enabledBorder: OutlineInputBorder( 138 borderRadius: BorderRadius.circular(2), 139 borderSide: const BorderSide( 140 color: Color.fromARGB(255, 219, 219, 219), //outlineの文字の色 141 width: 1.0, 142 ), 143 ), 144 focusedBorder: OutlineInputBorder( 145 borderRadius: BorderRadius.circular(2), 146 borderSide: const BorderSide( 147 color: Color.fromARGB(255, 219, 219, 219), //outline-focusの色 148 width: 1.0, //outlineの太さ 149 )), 150 ), 151 )); 152 } 153} 154
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/08/15 05:48
2022/08/15 06:21
2022/08/15 06:30
2022/08/15 07:22