[英]Call a method inside custom widget
我创建了一个自定义小部件。 它包括带有后缀 IconButton 的只读 TextFormField、API、警报对话框和回调 function 小部件可以处于 2 种状态,设置或重置。
通过 TextFormField 上的 IconButton 将小部件置于设置状态,这将执行 API 调用,返回的数据显示在 TextFormField 上。
根据某些应用程序要求,从父屏幕重置小部件。
我已经在我的各种活动(屏幕)中导入并使用了这个自定义小部件。 他们在我的屏幕上我希望清除我的自定义小部件,并且我已经创建了 clear 方法。
我想知道我将把这个clearWidget
方法称为谁。
如果需要,我可以clearWidget
方法到class GetTimeWidget extends StatefulWidget
enum TimeWidgetEvent { Start, Stop }
class GetTimeWidget extends StatefulWidget {
Ref<String> time;
final TimeWidgetEvent mode;
final String label;
const GetTimeWidget({
required this.time,
required this.mode,
required this.label,
Key? key,
}) : super(key: key);
@override
State<GetTimeWidget> createState() => _GetTimeWidgetState();
}
class _GetTimeWidgetState extends State<GetTimeWidget> {
final TextEditingController controller;
@override
Widget build(BuildContext context) {
return TextFormField(
controller: controller,
readOnly: true,
//initialValue: ,
decoration: InputDecoration(
label: Text(widget.label),
hintText: 'Please Get ${widget.label} from sever',
suffixIcon: TextButton.icon(
onPressed: () {
//Execute API to get time
},
icon: (widget.mode == TimeWidgetEvent.Start)
? const Icon(Icons.play_circle)
: const Icon(Icons.stop_circle),
label: (widget.mode == TimeWidgetEvent.Start)
? const Text('Start')
: const Text('Stop'),
),
border: const OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Get ${widget.label} from server'; //Validation error
}
return null; //Validation Success
},
);
}
void clearWidget()
{
controller.clear();
//Execute API
}
}
我认为你不能。 因为 state class 是私有的,并且 class (_GetTimeWidgetState) 中的每个方法都不能从外部调用。 如果我正确理解你想要做什么,就是从这个小部件外部更改 _GetTimeWidgetState 的内部 state。
我认为你不能。 My suggest is to use one of the state managers that you can find for flutter, like Riverpod (my choice), or Cubit, Get/Getx, etc... In that manner you can read/change the internal state using the global state由 state 管理器管理。
例如,使用 Riverpod,您可以定义一个处理数据的 StateClass:
final myProvider = StateNotifierProvider<MyStateNotifier, MyState>((ref) {
return MyStateNotifier("someInitialDataInfo");
});
class MyStateNotifier extends StateNotifier<MyState> {
MyStateNotifier("someInitialDataInfo") : super( MyState("someInitialDataInfo"));
void clear(String someDataInfo) { state = MyState( someDataInfo) ;}
}
@immutable
class MyState {
..... }
然后在您的 ComsumerState 中(在 Riverpod 中您应该使用 ConsumerStatefulWidget 和 ConsumerState),您可以在此处查看通知程序:
class _GetTimeWidgetState extends ConsumerState<GetTimeWidget> {
final TextEditingController controller;
@override
Widget build(BuildContext context, WidgetRef ref) {
final myState = ref.watch(myProvider );
if ( myState.someDataInfo == 'Clicked Reset!!!!' ) {
controller.clear();
}
return TextFormField( .... );
}
.... } ...}
现在,观察当通知程序 class 内的 state 发生变化时,将调用构建方法。 因此,每次更改都会通知您一次。 在 StateNotifier class(用于扩展和定义 MyStateNotifier 类的 class)内部将执行以下匹配以将您的小部件置于脏状态:
state != oldState
这意味着每次您更改内部 state 字段时,它都会将您的小部件放入脏 state,因此它将被重新构建。 MyState
class 被定义为@immutable
,因此每个 state 更改都不能通过以下方式完成:
state.setMyField ( ' my value ' );
但将完成更改 state object 本身:
state = MyState ( ... );
或使用其复制方法:
state = state.copyWith( .... ) ;
通过这种方式,您可以避免一些副作用( state 应该始终是不可变的)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.