当前位置: 首页 > news >正文

建设网站建设费用关键词自动生成器

建设网站建设费用,关键词自动生成器,wordpress免费模版,移动微网站开发一、Android界面渲染流程UI树与FlutterUI树的设计思路对比 二、Widget组件生命周期详解 1、Widget组件生命周期 和其他的视图框架比如android的Activity一样,flutter中的视图Widget也存在生命周期,生命周期的回调函数体现在了State上面。组件State的生命…

一、Android界面渲染流程UI树与FlutterUI树的设计思路对比

二、Widget组件生命周期详解

1、Widget组件生命周期

和其他的视图框架比如android的Activity一样,flutter中的视图Widget也存在生命周期,生命周期的回调函数体现在了State上面。组件State的生命周期整理如下图所示:

createState:

当一个StatefulWidget插入到渲染树结构、或者从渲染树结构移除时,都会调用StatefulWidget.createState方法,从而达到更新UI的效果;

initState:

initState是StatefulWidget创建后调用的第一个方法,而且只执行一次。在执行initState时,View没有渲染,但是StatefulWidget 已经被加载到渲染树里了;

didChangeDependencies:

didChangeDependencies会在initState后立即调用,当StatefulWidget依赖的InheritedWidget发生变化之后,didChangeDependencies会调用,所以didChangeDependencies可以调用多次;

build:

build方法会在didChangeDeoendencies之后立即调用,在之后setState()刷新时,会重新调用build绘制页面,所以build方法可以调用多次。一般不在build中创建除了创建Widget的方法,否则会影响渲染效率。

setState:

[State] 对象可以通过调用它们的 [setState]方法自发地请求重建其子树,这表明它们的某些内部状态已经改变,可能会影响该子树中的用户界面,setState方法会被多次调用。

didUpdateWidget:

1、当调用setState更新UI的时候,都会调用didUpdateWidget;

2、框架在调用[didUpdateWidget]之后总是调用[build],在[didUpdateWidget]中对[setState]的任何调用都是多余的。

deactivate:

1、当框架从树中移除此 State 对象时将会调用此方法;

2、在某些情况下,框架将重新插入State 对象到树的其他位置(例如,如果包含该树的子树State 对象从树中的一个位置移植到另一位置),框架将会调用 build 方法来提供 State 对象适应其在树中的新位置。

dispose:

当框架从树中永久移除此 State对象时将会调用此方法,与deactivate的区别是,deactivate 还可以重新插入到树中,而 dispose 表示此 State对象永远不会在 build。调用完 dispose后,mounted 属性被设置为false,也代表组件生命周期的结束,此时再调用setState方法将会抛出异常。子类重写此方法,释放相关资源,比如动画等。

2、生命周期调用

A Page:
import 'package:flutter/material.dart';
import 'package:flutter_app/pages/DemoPages.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: const Demo(),);}
}class Demo extends StatefulWidget {const Demo({super.key});@overrideState<Demo> createState() => _DemoState();
}class _DemoState extends State<Demo> {@overrideWidget build(BuildContext context) {print("------main--------build");return Scaffold(appBar: AppBar(title: const Text("StatefulWidget key"),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[ElevatedButton(onPressed: (){Navigator.of(context).push(MaterialPageRoute(builder:(setting){return const DemoPage();}));},child: const Text("页面跳转"),),],),),floatingActionButton: FloatingActionButton(onPressed: (){setState(() {print("调用....");});},tooltip: 'Increment',child: const Icon(Icons.add),), // This trailing comma makes auto-formatting nicer for build methods.);}@overridevoid initState() {// TODO: implement initStatesuper.initState();print("------main--------initState");}@overridevoid didChangeDependencies() {// TODO: implement didChangeDependenciessuper.didChangeDependencies();print("-------main-------didChangeDependencies");}@overridevoid setState(VoidCallback fn) {// TODO: implement setStatesuper.setState(fn);print("------main--------setState");}@overridevoid deactivate() {// TODO: implement deactivatesuper.deactivate();print("------main--------deactivate");}@overridevoid dispose() {// TODO: implement disposesuper.dispose();print("------main--------dispose");}
}
B Page:

import 'package:flutter/material.dart';class DemoPage extends StatelessWidget {const DemoPage({super.key}) ;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Demo页面"),),body: const DemoWidget(),);}
}class DemoWidget extends StatefulWidget {const DemoWidget({super.key});@overrideState<DemoWidget> createState() => _DemoWidgetState();
}class _DemoWidgetState extends State<DemoWidget> {String btnText = "test";@overrideWidget build(BuildContext context) {print("------_DemoWidgetState--------build");return Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[ElevatedButton(onPressed: (){setState(() {if(btnText == "test"){btnText = "测试";}else{btnText = "test";}});},child: Text(btnText),),ElevatedButton(onPressed: (){print("返回......");Navigator.of(context).pop();},child: const Text("返回"),),],),);}@overridevoid initState() {// TODO: implement initStatesuper.initState();print("------_DemoWidgetState--------initState");}@overridevoid didChangeDependencies() {// TODO: implement didChangeDependenciessuper.didChangeDependencies();print("-------_DemoWidgetState-------didChangeDependencies");}@overridevoid setState(VoidCallback fn) {// TODO: implement setStatesuper.setState(fn);print("------_DemoWidgetState--------setState");}@overridevoid deactivate() {// TODO: implement deactivatesuper.deactivate();print("------_DemoWidgetState--------deactivate");}@overridevoid dispose() {// TODO: implement disposesuper.dispose();print("-----_DemoWidgetState---------dispose");}
}

三、页面间数据传递(共享)的几种常用方式

公共页面:

import 'package:flutter/material.dart';
import 'transfer_constructor_page.dart';
import 'transfer_data_entity.dart';
import 'transfer_data_inherited.dart';
import 'transfer_data_singleton.dart';
import 'transfer_router_page.dart';
import 'transfer_singleton_page.dart';
import 'transfer_stream_singleton.dart';
import 'transfer_stream_singleton_page.dart';import 'inherited_data_provider.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {// This widget is the root of your application.var params = TransferDataEntity(name:"王五", id:"009", age:16);@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Data Transfer Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: const MyHomePage(title: 'Data Transfer Demo'),);}
}class MyHomePage extends StatefulWidget {const MyHomePage({super.key, required this.title});final String title;@override_MyHomePageState createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {var data = TransferDataEntity(name:"张三丰", id:"001", age:18);List<String> itemNames = ["构造器传递数据","返回上个页面时携带参数","InheritedWidget方式","Singleton方式","Singleton结合Stream",];@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),),body: Column(children: <Widget>[Container(alignment: Alignment.center,height: 60.0,color: Colors.black12,child: Text("${data.id},${data.name},${data.age}")),Expanded(child: ListView.separated(separatorBuilder: (BuildContext contex, int index) {return const Divider(color: Colors.black12,height: 0.5,);},itemBuilder: (BuildContext context, int index) {return InkWell(onTap: () => _onClick(index, data, context),child: Container(alignment: Alignment.center,height: 48.0,width: double.infinity,child:  Text(itemNames[index],style: const TextStyle(color: Colors.black,fontWeight: FontWeight.bold,fontSize: 14.0,),),),);},itemCount: itemNames.length,),),],),floatingActionButton: FloatingActionButton(onPressed: () {},tooltip: 'Increment',child: const Icon(Icons.add),), // This trailing comma makes auto-formatting nicer for build methods.);}_onClick(int index, TransferDataEntity data, BuildContext context) {switch (index) {case 0:_transferDataByConstructor(context, data);break;case 1:_toTransferForResult(context, data);break;case 2:_inheritedToPage(context, data);break;case 3:_singletonDataTransfer(context);break;case 4:_streamDataTransfer(context);break;}}//通过构造器方法传递数据_transferDataByConstructor(BuildContext context, TransferDataEntity data) {Navigator.push(context,MaterialPageRoute(builder: (context) => DataTransferByConstructorPage(data: data)));}_toTransferForResult(BuildContext context, TransferDataEntity data) async {final dataFromOtherPage = await Navigator.push(context,MaterialPageRoute(builder: (context) => TransferRouterPage(data: data)),) as TransferDataEntity;setState(() {data.name = dataFromOtherPage.name;data.id = dataFromOtherPage.id;data.age = dataFromOtherPage.age;});}_inheritedToPage(BuildContext context, TransferDataEntity data) {Navigator.push(context,MaterialPageRoute(builder: (context) => IDataProvider(data: data,child: IDataWidget(),)));}_singletonDataTransfer(BuildContext context) {var transferData = TransferDataEntity(name:"三喵2", id:"002", age:20);transSingletonData.transData = transferData;Navigator.push(context,MaterialPageRoute(builder: (context) => TransferSingletonPage()));}_streamDataTransfer(BuildContext context) {var transferData = TransferDataEntity(name:"三喵", id:"005", age:20);streamSingletonData.setTransferData(transferData);Navigator.push(context,MaterialPageRoute(builder: (context) => TransferStreamPage()));}
}

1、通过构造器(constructor)传递数据

通过构造器传递数据是一种最简单的方式,也是最常用的方式,在第一个页面,我们模拟创建一个我们需要传递数据的对象。当点击跳转的时候,我们把数据传递DataTransferByConstructorPage页面,并把携带过来的数据展示到页面上。

1)创建一个传递数据对象 :final data=TransferDataEntity("001","张三丰",18);

2)定义一个跳转到DataTransferByConstructorPage页面的方法:

3)在DataTransferByConstructorPage页面接收到数据并展示出来:

import 'package:flutter/material.dart';
import 'transfer_data_entity.dart';///通过构造器的方式传递参数
class DataTransferByConstructorPage extends StatelessWidget {final TransferDataEntity data;const DataTransferByConstructorPage({super.key, required this.data});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("构造器方式"),),body: Column(children: <Widget>[Container(width: double.infinity,height: 40.0,alignment: Alignment.center,child: Text(data.id),),Container(width: double.infinity,height: 40.0,alignment: Alignment.center,child: Text(data.name),),Container(width: double.infinity,height: 40.0,alignment: Alignment.center,child: Text("${data.age}"),)],),);}
}

2、当一个页面关闭时携带数据到上一个页面(Navigator.pop)

在Android开发中我们需要将数据传递给上一个页面通常使用的传统方式是startActivityForResult()方法。但是在flutter就不用这么麻烦了。只需要使用Navigator.pop方法即可将数据结果带回去。但是我们跳转的时候需要注意两点:

1)我们需要定义一个异步方法用于接收返回来的结果:

2)在我们要关闭的页面使用Navigator.pop 返回第一个页面:

import 'package:flutter/material.dart';
import 'transfer_data_entity.dart';class TransferRouterPage extends StatelessWidget {final TransferDataEntity data;const TransferRouterPage({super.key, required this.data});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("返回上个页面传递参数"),leading: Builder(builder: (BuildContext context) {return IconButton(icon: const Icon(Icons.arrow_back_ios),onPressed: () {_backToData(context);});}),),body: Column(children: <Widget>[Container(alignment: Alignment.center,height: 40.0,child: Text(data.name),),Container(alignment: Alignment.center,height: 40.0,child: Text(data.id),),Container(alignment: Alignment.center,height: 40.0,child: Text("${data.age}"),),ElevatedButton(onPressed: () {_backToData(context);},child: const Text("点我返回上一个页面并把数据传回去"))],),);}//返回并携带数据_backToData(BuildContext context) {var transferData = TransferDataEntity(name: "嘻嘻哈哈", id: "007", age: 20);Navigator.pop(context, transferData);}
}

3、InheritedWidget方式 

使用lnheritedWidget方式如下几步:

1)继承lnheritedWidget提供一个数据源:

import 'package:flutter/material.dart';
import 'transfer_data_entity.dart';//所有的子组件共享数据
class IDataProvider extends InheritedWidget {final TransferDataEntity data;const IDataProvider({super.key, required super.child, required this.data});@overridebool updateShouldNotify(IDataProvider oldWidget) {return data != oldWidget.data;}//版本问题//InheritedWidgetstatic IDataProvider? of(BuildContext context) {return context.dependOnInheritedWidgetOfExactType<IDataProvider>();}// static _InheritedProviders of(BuildContext context) {
//   final widget = context.inheritFromWidgetOfExactType(_InheritedProviders);
//   return widget is _InheritedProviders ? widget : null;
// }}

2)定义页面跳转时候携带数据的方法:

3)跳转的到的页面并展示数据代码如下:

import 'package:flutter/material.dart';import 'inherited_data_provider.dart';class IDataWidget extends StatelessWidget {const IDataWidget({super.key});@overrideWidget build(BuildContext context) {final data = IDataProvider.of(context)!.data;return Scaffold(appBar: AppBar(title: const Text("Inherited方式传递数据"),),body: Column(children: <Widget>[Container(alignment: Alignment.center,height: 40.0,child: Text(data.name),),Container(alignment: Alignment.center,height: 40.0,child: Text(data.id),),Container(alignment: Alignment.center,height: 40.0,child: Text("${data.age}"),),const IDataChildWidget()],),);}
}class IDataChildWidget extends StatelessWidget {const IDataChildWidget({super.key});@overrideWidget build(BuildContext context) {final data = IDataProvider.of(context)!.data;return Text(data.name);}
}

4、全局的提供数据的方式

这种方式我们还是使用lnheritedWidget,区别就是我们不是跳转的时候去创建IGenericDataProvider。而是把他放在最顶层注意:这种方式一定要把数据放在顶层;

1)定义顶部数据:

2)接收数据的方式基本和 lnheritedWidget相同:

final data=IGenericDataProvider.of<TransferDataEntity>(context) 获取数据

3)使用代码:

5、通过全局单例模式来使用 

这种方式就是创建一个全局单例对象,任何地方都可以操控这个对象,存储和取值都可以通过这个对象。

1)创建单例对象:

import 'transfer_data_entity.dart';class TransferDataSingleton {static final TransferDataSingleton _instanceTransfer =TransferDataSingleton.__internal();TransferDataEntity? transData;factory TransferDataSingleton() {return _instanceTransfer;}TransferDataSingleton.__internal();
}final transSingletonData = TransferDataSingleton();

 2)给单例对象存放数据:

3)接收并使用传递的值:

import 'package:flutter/material.dart';
import 'transfer_data_singleton.dart';class TransferSingletonPage extends StatefulWidget {const TransferSingletonPage({super.key});@override_TransferSingletonPageState createState() => _TransferSingletonPageState();
}class _TransferSingletonPageState extends State<TransferSingletonPage> {@overrideWidget build(BuildContext context) {var data = transSingletonData.transData;return Scaffold(appBar: AppBar(title: const Text("全局单例传递数据"),),body: Column(children: <Widget>[Container(alignment: Alignment.center,height: 40.0,child: Text(data!.name),),Container(alignment: Alignment.center,height: 40.0,child: Text(data.id),),Container(alignment: Alignment.center,height: 40.0,child: Text("${data.age}"),),],),);}
}

6、全局单例结合Stream的方式传递数据

1)单例模式:

import 'dart:async';import 'transfer_data_entity.dart';class TransferStreamSingleton {static final TransferStreamSingleton _instanceTransfer =TransferStreamSingleton.__internal();StreamController? streamController;void setTransferData(TransferDataEntity transData) {streamController = StreamController<TransferDataEntity>();streamController!.sink.add(transData);}factory TransferStreamSingleton() {return _instanceTransfer;}TransferStreamSingleton.__internal();
}final streamSingletonData = TransferStreamSingleton();

2)传递要携带的数据:

3)接收要传递的值:

import 'dart:async';import 'package:flutter/material.dart';
import 'transfer_data_entity.dart';
import 'transfer_stream_singleton.dart';class TransferStreamPage extends StatefulWidget {const TransferStreamPage({super.key});@override_TransferStreamPageState createState() => _TransferStreamPageState();
}class _TransferStreamPageState extends State<TransferStreamPage> {final StreamController? _streamController =streamSingletonData.streamController;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("全局单例结合Stream"),),body: StreamBuilder(stream: _streamController!.stream,initialData: TransferDataEntity(),builder: (context, snapshot) {return Column(children: <Widget>[Container(alignment: Alignment.center,height: 40.0,child: Text(snapshot.data.name),),Container(alignment: Alignment.center,height: 40.0,child: Text(snapshot.data.id),),Container(alignment: Alignment.center,height: 40.0,child: Text("${snapshot.data.age}"),),],);}));}@overridevoid dispose() {_streamController?.close();super.dispose();}
}

四、Flutter Key

我们平时一定接触过很多的Widget,比如 Container、Row、Column等,它们在我们绘制界面的过程中发挥着重要的作用。但是不知道你有没有注意到,在几乎每个Widget的构造函数中,都有一个共同的参数,它们通常在参数列表的第一个,那就是Key。

在Flutter中,Key是不能重复使用的,所以Key一般用来做唯一标识。组件在更新的时候,其状态的保存主要是通过判断组件的类型或者key值是否一致。因此,当各组件的类型不同的时候,类型已经足够用来区分不同的组件了,此时我们可以不必使用key。但是如果同时存在多个同一类型的控件的时候,此时类型已经无法作为区分的条件了,我们就需要使用到key。 

1、没有Key 会发生什么现象:

如下面例:定义了一个StatefulWidget的Box,点击Box的时候可以改变Box里面的数字,当我们重新对Box排序的时候,Flutter就无法识别到Box的变化了,这是什么原因呢?

运行后我们发现改变list Widget顺序后,Widget颜色会变化,但是每个Widget里面的文本内容并没有变化,为什么会这样呢?当我们List重新排序后Flutter检测到了Widget的顺序变化,所以重新绘制List Widget,但是Flutter发现List Widget里面的元素没有变化,所以就没有改变Widget里面的内容。

把List 里面的Box的颜色改成一样,这个时候您重新对list进行排序,就很容易理解了。重新排序后虽然 执行了setState,但Flutter没法通过Box里面传入的参数是代码和以前是一样的,所以Flutter不会重构List Widget里面的内容,也就是来识别Box是否改变。如果要让FLutter能识别到List Widget子元素的改变,就需要给每个Box指定一个key。 

实现代码:

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: const MyHomePage(),);}
}class MyHomePage extends StatefulWidget {const MyHomePage({super.key});@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {List<Widget> list = [// Center(//   child: Box(//     color: Colors.blue,//   ),// ),Box(color: Colors.blue,),Box(color: Colors.red,),Box(color: Colors.orange,)];@overrideWidget build(BuildContext context) {return Scaffold(floatingActionButton: FloatingActionButton(onPressed: () {setState(() {list.shuffle(); //打乱list的顺序});},child: const Icon(Icons.refresh),),appBar: AppBar(title: const Text('Title'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: list,),),);}
}class Box extends StatefulWidget {Color color;Box({super.key, required this.color});@overrideState<Box> createState() => _BoxState();
}class _BoxState extends State<Box> {int _count = 0;@overrideWidget build(BuildContext context) {return SizedBox(height: 100,width: 100,child: ElevatedButton(style: ButtonStyle(backgroundColor: MaterialStateProperty.all(widget.color)),onPressed: () {setState(() {_count++;});},child: Center(child: Text("$_count"),),),);}
}

2、LocalKey与GlobalKey

在Flutter中,Key是不能重复使用的,所以Key一般用来做唯一标识。组件在更新的时候,其状态的保存主要是通过判断组件的类型或者key值是否一致。因此,当各组件的类型不同的时候,类型已经足够用来区分不同的组件了,此时我们可以不必使用key。但是如果同时存在多个同一类型的控件的时候,此时类型已经无法作为区分的条件了,我们就需要使用到key。

 

运用key变更上面案例业务:

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: const MyHomePage(),);}
}class MyHomePage extends StatefulWidget {const MyHomePage({super.key});@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {List<Widget> list = [Center(key: UniqueKey(),child: Box(color: Colors.blue,),),// Box(//   // key: const ValueKey("1"),//指定值//   color: Colors.blue,// ),Box(key: UniqueKey(), //唯一值, 自动生成color: Colors.red,),Box(key: const ObjectKey("2"), //类似于ValueKey// key: const ObjectKey(2),//类似于ValueKeycolor: Colors.orange,)];@overrideWidget build(BuildContext context) {return Scaffold(floatingActionButton: FloatingActionButton(onPressed: () {setState(() {list.shuffle(); //打乱list的顺序});},child: const Icon(Icons.refresh),),appBar: AppBar(title: const Text('Title'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: list,),),);}
}class Box extends StatefulWidget {Color color;Box({super.key, required this.color});@overrideState<Box> createState() => _BoxState();
}class _BoxState extends State<Box> {int _count = 0;_BoxState() {print("--------_BoxState----------构造");}@overrideWidget build(BuildContext context) {print("------_BoxState--------build");return SizedBox(height: 100,width: 100,child: ElevatedButton(style: ButtonStyle(backgroundColor: MaterialStateProperty.all(widget.color)),onPressed: () {setState(() {_count++;});},child: Center(child: Text("$_count"),),),);}@overridevoid initState() {// TODO: implement initStatesuper.initState();print("------_BoxState--------initState");}@overridevoid didChangeDependencies() {// TODO: implement didChangeDependenciessuper.didChangeDependencies();print("-------_BoxState-------didChangeDependencies");}@overridevoid setState(VoidCallback fn) {// TODO: implement setStatesuper.setState(fn);print("------_BoxState--------setState");}@overridevoid deactivate() {// TODO: implement deactivatesuper.deactivate();print("------_BoxState--------deactivate");}@overridevoid dispose() {// TODO: implement disposesuper.dispose();print("------_BoxState--------dispose");}
}

3、GlobalKey的使用

如果把LocalKey比作局部变量,GlobalKey就类似于全局变量;

下面使用了LocalKey,当屏幕状态改变的时候把Colum换成了Row,Box的状态就会丢失。一个Widget状态的保存主要是通过判断组件的类型或者key值是否一致。 LocalKey只在当前的组件树有效,所以把Colum换成了Row的时候Widget的状态就丢失了。

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: const MyHomePage(),);}
}class MyHomePage extends StatefulWidget {const MyHomePage({super.key});@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {List<Widget> list = [Box(key: const ValueKey(1), //int double stringcolor: Colors.blue,),Box(key: ObjectKey(Object()),color: Colors.red,),Box(key: UniqueKey(), //程序自动生成一个keycolor: Colors.orange,)];@overrideWidget build(BuildContext context) {return Scaffold(floatingActionButton: FloatingActionButton(onPressed: () {setState(() {list.shuffle(); //打乱list的顺序});},child: const Icon(Icons.refresh),),appBar: AppBar(title: const Text('Title'),),body: Center(child: MediaQuery.of(context).orientation == Orientation.portrait? Column(mainAxisAlignment: MainAxisAlignment.center,children: list,): Row(mainAxisAlignment: MainAxisAlignment.center,children: list,),),);}
}class Box extends StatefulWidget {Color color;Box({super.key, required this.color});@overrideState<Box> createState() => _BoxState();
}class _BoxState extends State<Box> {int _count = 0;@overrideWidget build(BuildContext context) {return SizedBox(height: 100,width: 100,child: ElevatedButton(style: ButtonStyle(backgroundColor: MaterialStateProperty.all(widget.color)),onPressed: () {setState(() {_count++;});},child: Center(child: Text("$_count"),),),);}
}

为了解决这个问题我们就可以使用GlobalKey。

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: const MyHomePage(),);}
}class MyHomePage extends StatefulWidget {const MyHomePage({super.key});@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {// List<Widget> list = [//   Box(//     key: const ValueKey(1),//     color: Colors.blue,//   ),//   Box(//     key: ObjectKey(Box(color: Colors.red)),//     color: Colors.red,//   ),//   Box(//     key:UniqueKey(), //程序自动生成一个key//     color: Colors.orange,//   )// ];List<Widget> list = [Box(key: GlobalKey(),color: Colors.blue,),Box(key: GlobalKey(),color: Colors.red,),Box(key: GlobalKey(), //程序自动生成一个keycolor: Colors.orange,)];@overrideWidget build(BuildContext context) {return Scaffold(floatingActionButton: FloatingActionButton(onPressed: () {setState(() {list.shuffle(); //打乱list的顺序});},child: const Icon(Icons.refresh),),appBar: AppBar(title: const Text('Title'),),body: Center(child: MediaQuery.of(context).orientation == Orientation.portrait? Column(mainAxisAlignment: MainAxisAlignment.center,children: list,): Row(mainAxisAlignment: MainAxisAlignment.center,children: list,),),);}
}class Box extends StatefulWidget {Color color;Box({super.key, required this.color});@overrideState<Box> createState() => _BoxState();
}class _BoxState extends State<Box> {int _count = 0;@overrideWidget build(BuildContext context) {return SizedBox(height: 100,width: 100,child: ElevatedButton(style: ButtonStyle(backgroundColor: MaterialStateProperty.all(widget.color)),onPressed: () {setState(() {_count++;});},child: Center(child: Text("$_count"),),),);}
}

4、GlobalKey 获取子组件

globalKey.currentState 可以获取子组件的状态,执行子组件的方法,globalKey.currentWidget可以获取子组件的属性,_globalKey.currentContext!.findRenderObject()可以获取渲染的属性。

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: const HomePage(),);}
}class HomePage extends StatefulWidget {const HomePage({super.key});@overrideState<HomePage> createState() => _HomePageState();
}class _HomePageState extends State<HomePage> {final GlobalKey _globalKey = GlobalKey();@overrideWidget build(BuildContext context) {return Scaffold(floatingActionButton: FloatingActionButton(child: const Icon(Icons.add),onPressed: () {//1、获取子组件的状态 调用子组件的属性var state = (_globalKey.currentState as _BoxState);setState(() {state._count++;});//2、获取子组件的属性var box = (_globalKey.currentWidget as Box);print(box.color);//3、获取子组件渲染的属性var renderBox =(_globalKey.currentContext?.findRenderObject() as RenderBox);print(renderBox.size);},),appBar: AppBar(title: const Text('Title'),),body: Center(child: Box(key: _globalKey,color: Colors.red,),),);}
}class Box extends StatefulWidget {final Color color;const Box({super.key, required this.color});@overrideState<Box> createState() => _BoxState();
}class _BoxState extends State<Box> {int _count = 0;run() {print("run");}@overrideWidget build(BuildContext context) {return SizedBox(height: 100,width: 100,child: ElevatedButton(style: ButtonStyle(backgroundColor: MaterialStateProperty.all(widget.color)),onPressed: () {setState(() {_count++;});},child: Center(child: Text("$_count"),),),);}
}

 

 

http://www.khdw.cn/news/49846.html

相关文章:

  • 面试学校网站开发东莞seo外包
  • wordpress板娘插件武汉seo收费
  • 房地产公司如何做网站怎么找一手app推广代理
  • 怎么做企业网站快手作品免费推广软件
  • 一元建站镇江seo
  • 网站页面打开速度慢搜索引擎优化方法与技巧
  • 江苏政府网站建设对比评估营销咨询服务
  • 杭州网站建设教育机构如何提高搜索引擎优化
  • 定制型网站关键词排名点击软件首页
  • 18成年人正能量软件长沙网站seo公司
  • 主机安装wordpress班级优化大师网页版
  • 北京工信部网站备案查询中国搜索引擎有哪些
  • 360门户网站怎样做工业设计公司
  • 网站密钥怎么做最近的新闻有哪些
  • wordpress 资讯官网seo是什么意思
  • 3g下订单的网站怎么做做推广的软件有哪些
  • 薪火相传网站建设刚刚刚刚刚刚刚刚刚刚刚刚刚刚
  • 有哪些外国网站做精油的企业推广软文
  • 如何做360购物网站找精准客户的app
  • 仁怀网站建设不好出手关键词seo排名
  • 网站提现功能开发网站建设服务公司
  • 金融视频直播网站开发b站2023年免费入口
  • 网上做批发的网站兰蔻搜索引擎营销案例
  • 哪类公司做网站的最多百度推广客户端
  • 做纱线的网站做一个网站的步骤
  • 做网站单页视频如何自建网站
  • 万州网站建设淄博搜索引擎优化
  • 临汾做网站公司b2b平台有哪些
  • 彩票类网站是如何做代理的惠州seo推广公司
  • 做网站很挣多少钱有链接的网站