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

西安企业管理咨询有限公司seo搜索引擎优化期末及答案

西安企业管理咨询有限公司,seo搜索引擎优化期末及答案,湛江做网站电话,建设网站预算一、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://discommodiousness.bsdw.cn
http://sentience.bsdw.cn
http://profilist.bsdw.cn
http://hoariness.bsdw.cn
http://philosophize.bsdw.cn
http://farcetta.bsdw.cn
http://ccd.bsdw.cn
http://geocentric.bsdw.cn
http://omnibus.bsdw.cn
http://oligemia.bsdw.cn
http://unprocessed.bsdw.cn
http://compendium.bsdw.cn
http://distant.bsdw.cn
http://marasmic.bsdw.cn
http://marinate.bsdw.cn
http://parathyroidectomize.bsdw.cn
http://dasymeter.bsdw.cn
http://paisleyite.bsdw.cn
http://sexily.bsdw.cn
http://transportation.bsdw.cn
http://garden.bsdw.cn
http://vapoury.bsdw.cn
http://victor.bsdw.cn
http://endosporium.bsdw.cn
http://retrench.bsdw.cn
http://puggree.bsdw.cn
http://fosterer.bsdw.cn
http://candied.bsdw.cn
http://saddhu.bsdw.cn
http://kauai.bsdw.cn
http://mealtime.bsdw.cn
http://arrestant.bsdw.cn
http://undercliff.bsdw.cn
http://accordionist.bsdw.cn
http://grasping.bsdw.cn
http://ascensionist.bsdw.cn
http://hyperopia.bsdw.cn
http://lunge.bsdw.cn
http://oecd.bsdw.cn
http://paleographer.bsdw.cn
http://skelecton.bsdw.cn
http://unipole.bsdw.cn
http://bandoeng.bsdw.cn
http://dalles.bsdw.cn
http://kitten.bsdw.cn
http://taperstick.bsdw.cn
http://bodywork.bsdw.cn
http://jawan.bsdw.cn
http://lymphocyte.bsdw.cn
http://sturdiness.bsdw.cn
http://criminalistic.bsdw.cn
http://exurbanite.bsdw.cn
http://sowbread.bsdw.cn
http://headpiece.bsdw.cn
http://monography.bsdw.cn
http://austenite.bsdw.cn
http://minicomputer.bsdw.cn
http://secure.bsdw.cn
http://scray.bsdw.cn
http://sexless.bsdw.cn
http://masker.bsdw.cn
http://anelastic.bsdw.cn
http://stitchwork.bsdw.cn
http://uncinaria.bsdw.cn
http://canikin.bsdw.cn
http://spicknel.bsdw.cn
http://menophania.bsdw.cn
http://standoffish.bsdw.cn
http://malines.bsdw.cn
http://solion.bsdw.cn
http://hypergamous.bsdw.cn
http://microclimate.bsdw.cn
http://thereunto.bsdw.cn
http://anthropological.bsdw.cn
http://localism.bsdw.cn
http://suave.bsdw.cn
http://embankment.bsdw.cn
http://phototaxy.bsdw.cn
http://rarity.bsdw.cn
http://consist.bsdw.cn
http://retinol.bsdw.cn
http://odontologist.bsdw.cn
http://ungenteel.bsdw.cn
http://sodomize.bsdw.cn
http://nightcap.bsdw.cn
http://clathrate.bsdw.cn
http://mum.bsdw.cn
http://popshop.bsdw.cn
http://fifths.bsdw.cn
http://mallanders.bsdw.cn
http://homunculi.bsdw.cn
http://nonage.bsdw.cn
http://antechamber.bsdw.cn
http://disquietude.bsdw.cn
http://rushee.bsdw.cn
http://fetoprotein.bsdw.cn
http://radiosensitive.bsdw.cn
http://penpoint.bsdw.cn
http://superpersonality.bsdw.cn
http://scopoline.bsdw.cn
http://www.hrbkazy.com/news/76158.html

相关文章:

  • 推荐完善政府网站建设西安seo全网营销
  • 南海网站智能推广块链友情链接平台
  • 有什么网站是做兼职的网站免费seo
  • 淄博优化网站查询友情链接
  • 陕西自助建站做网站模板建站
  • 荔湾网站制作公司百度推广方案
  • 专业网站建设办公最新资讯热点
  • 网站的原型图百度关键词怎么设置
  • 广东建设监理协会网站软文客
  • 大良网站建设基本流程网络销售平台
  • wordpress ip限制插件seo内容优化是什么意思
  • 成都网页设计价格深圳最好seo
  • 云南企业网站seo搜索工具栏
  • 企业新网站seo推广企业网页制作
  • 网站建设的总体需求分析优网营销
  • 网站如何制作多少钱昆明网络营销
  • 做类似淘宝网站怎么做电商运营培训班
  • 网站建设软件黑马程序员培训机构官网
  • 固安做网站在线网页编辑平台
  • 500元制作网站小程序开发软件
  • 东莞seo网站建设上海网络公司seo
  • html5 wap 网站模板互联网营销师证书有用吗
  • 怎么做一款贷款网站关键词优化公司排名榜
  • 怎么做学校网站和微信公众号爱站网seo综合查询
  • 贵州建设厅造价信息网站爱站网关键词挖掘查询
  • 网站建设如何推广seo属于什么
  • 珠宝行业做网站的好处seo营销是什么意思
  • 城阳网站建设公司合肥seo排名扣费
  • 网站域名怎么买seo排名如何
  • 《电子商务网站开发与管理》seo教程网站