Изменение виджета состояния одного через другой виджет

#flutter #dart

Вопрос:

MyHomePageState:

 Widget build(BuildContext context) {  double screenWidth = MediaQuery.of(context).size.width;  return Scaffold(  backgroundColor: bgColor,  body: ListView(  children: lt;Widgetgt;[  Stack(  alignment: Alignment.topCenter,    children: lt;Widgetgt;[  mainWidget(),    ],  ),  connectedStatusText(),  ],  ));  }  

Я пытаюсь изменить статус connectedStatusText() из mainWidget()!

Мой подключенный статус:

 class connectedStatusText extends StatefulWidget {  Statelt;connectedStatusTextgt; createState() {  return connectedStatus();  } }  class connectedStatus extends Statelt;connectedStatusTextgt; {  String status = "IDLE";  @override  Widget build(BuildContext context) {  return Align(  alignment: Alignment.center,  child: RichText(  textAlign: TextAlign.center,  text: TextSpan(text: 'Status:', style: connectedStyle, children: [  TextSpan(text: status, style: disconnectedRed)  ]),  ),  );  }  }  

Я хочу изменить текст $status на «подключен» через ontap mainWidget().

mainWidget:

 .... class mainWidget extends StatefulWidget {  MyED createState() =gt; new MyED(); }   class MyED extends Statelt;mainWidgetgt; {  child: new GestureDetector(  onTap: () =gt; setState(() {  //change here  }  

попытался установить глобальную переменную в ConnectedStatus:

 GlobalKeylt;connectedStatusgt; key = GlobalKeylt;connectedStatusgt;();  

и изменить с помощью ontap…

 child: new GestureDetector(  onTap: () =gt; setState(() {  //change here  key.currentState.status = "CONNECTED";  }  ) }  

но это не работает! Есть ли у меня какая-нибудь помощь, чтобы изменить этот текст в другом месте?

Комментарии:

1. вы пытаетесь изменить значение дочернего виджета из родительского виджета?

Ответ №1:

Пожалуйста, обратитесь к приведенному ниже примеру кода для обновления состояния с помощью ValueNotifier и ValueListenableBuilder.

ValueNotifer и ValueListenableBuilder можно использовать для хранения значения и обновления виджета, уведомляя его слушателей и уменьшая количество перестроек дерева виджетов.

 import 'package:flutter/material.dart';  const Color darkBlue = Color.fromARGB(255, 18, 32, 47);  void main() {  runApp(MyApp()); }  class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {  return MaterialApp(  theme: ThemeData.dark().copyWith(  scaffoldBackgroundColor: darkBlue,  ),  debugShowCheckedModeBanner: false,  home: Screen2(),  );  } }  class Screen2 extends StatefulWidget {  final String userId; // receives the value   const Screen2({Key key, this.userId}) : super(key: key);   @override  _Screen2State createState() =gt; _Screen2State(); }  class _Screen2State extends Statelt;Screen2gt; {  final ValueNotifierlt;boolgt; updateStatus = ValueNotifier(false);  @override  Widget build(BuildContext context) {  double screenWidth = MediaQuery.of(context).size.width;  return Scaffold(  backgroundColor: Colors.blue,  body: ListView(  children: lt;Widgetgt;[  Stack(  alignment: Alignment.topCenter,  children: lt;Widgetgt;[  mainWidget(  updateStatus: updateStatus,  ),  ],  ),  connectedStatusText(  updateStatus: updateStatus,  ),  ],  ),  ); // uses the value  } }  class connectedStatusText extends StatefulWidget {  final ValueNotifierlt;boolgt; updateStatus;   connectedStatusText({  Key key,  this.updateStatus,  }) : super(key: key);   Statelt;connectedStatusTextgt; createState() {  return connectedStatus();  } }  class connectedStatus extends Statelt;connectedStatusTextgt; {  String status = "IDLE";   @override  Widget build(BuildContext context) {  return Align(  alignment: Alignment.center,  child: /*   In order update widget we can use ValueListenableBuilder which updates the particular widget when the value changes (ValueNotifier value)  */  ValueListenableBuilder(  valueListenable: widget.updateStatus,  builder: (context, snapshot, child) {  return RichText(  textAlign: TextAlign.center,  text: TextSpan(text: 'Status:', children: [  TextSpan(  text: (widget.updateStatus.value == true)  ? "Active"  : status,  )  ]),  );  }),  );  } }  class mainWidget extends StatefulWidget {  final String userId; // receives the value  final ValueNotifierlt;boolgt; updateStatus;   mainWidget({  Key key,  this.userId,  this.updateStatus,  }) : super(key: key);   @override  _mainWidgetState createState() =gt; _mainWidgetState(); }  class _mainWidgetState extends Statelt;mainWidgetgt; {  @override  Widget build(BuildContext context) {  return GestureDetector(  onTap: () {  widget.updateStatus.value = !widget.updateStatus.value;  },  child: ValueListenableBuilder(  valueListenable: widget.updateStatus,  builder: (context, snapshot, child) {  return Text(snapshot.toString());  }));   // uses the value  } }    

Комментарии:

1. Очень хорошо! не знал, что такое ValueListenableBuilder… Спасибо!

2. Спасибо. Надеюсь, это вам помогло