[英]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.