ウイジェットとRiverpod
拡張性を求められるアプリ開発にChangeNotifierProviderは勧められない、とのこと(公式)。
◎SliderウイジェットをRiverpodで使用する
・SliderウイジェットはsetStateを使って値を更新しないと反映されない。
・Riverpodでは、useStateを使い値を更新する。
(一部抜粋)
class ElemListPage extends HookConsumerWidget{
const ElemListPage ({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref){
var _AppConfigrProvider = ref.watch(gAppConfigrProvider);
Widget _makeElemItemHeightSliderWidget(){
final _slideExtentvalue = useState<double>(_AppConfigrProvider.ElemItemExtent);
return
Card(
child:
Padding(padding: EdgeInsets.all(2),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(AppLocalizations.of(context)!.elementHeightstring),
Expanded(child: SizedBox()),
Slider(
label: '${_slideHeightvalue.value}',
min: gMinElemItemHeight,
max: gMaxElemItemHeight,
divisions: gElemItemHeightDivision,
value: _slideHeightvalue.value,
onChanged:(inDouble){
_AppConfigrProvider.ElemItemHeight = inDouble;
_slideHeightvalue.value = inDouble;
_AppConfigrProvider.notifyListeners();
},
)
]
),
),
);
}
・hooks_riverpod.dartとflutter_hooks.dartをインポートする。
・HookConsumerWidgetを使用する。
・useStateを宣言する。
final _slideExtentvalue = useState<double>(_AppConfigrProvider.ElemItemExtent);
・値を変更するとSliderが更新される。
_slideHeightvalue.value = inDouble;
◎TextFieldウィジェットをRiverpodで使用する
・HookConsumerWidget では、TextEditingControllerだとうまく動かないため、
useTextEditingControllerを使用する。
(一部抜粋)
class ElemListPage extends HookConsumerWidget{
const ElemListPage ({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref){
var _TSVManagerProvider = ref.watch(gTSVManagerProvider);
final _editingController = useTextEditingController(); // TextEditingController だとうまく動かない
(一部抜粋)
TextField(
controller: _editingController,
decoration:
InputDecoration(
labelText: AppLocalizations.of(context)!.inputtextandaddstring, // テキストを入力してください、のラベル
),
// 表示を更新しないとボタンが更新されない。
// →Stateを更新するコードを入れるようにすれば動くと思う
onChanged: (String inStr) {_TSVManagerProvider.TSVNotifyListners();},
),
(一部抜粋)
// 追加ボタン
Opacity(opacity: (_editingController.text.isEmpty) ? 0.3 : 1.0, // テキストフィールドが空白の時は半透明
child:
FloatingActionButton(
tooltip: AppLocalizations.of(context)!.addelemstring,
child: const Icon(Icons.add),
onPressed: _editingController.text.isEmpty ? null : ()async { //テキストフィールドが空白の時は押せない
_TSVManagerProvider.InsertSelectedElemNonotify(_editingController.text);
_TSVManagerProvider.IsSelectedElem = false;
_editingController.text = "";
_TSVManagerProvider.TSVNotifyListners();
//delay を入れて、jumptoが使えるようにする
await Future.delayed(const Duration(milliseconds: 100));
if (_TSVManagerProvider.IsAddBeforeElement == false) {
_gElemListControler.jumpTo(_gElemListControler.position.maxScrollExtent);
}
},
),
・_TSVManagerProvider.TSVNotifyLisners()は、任意のタイミングでnotifylistners()を呼び出したいときに使用している。
notifylistners()を呼ばないと、_editingController.text.isEmptyもうまくいかないし、FloatingActionButtonの透明化が反映されない。
→stateを更新するコードを書けばよいはず。