赞
踩
在理解这些问题之前,建议看一下Flutter架构原理,如下链接:
https://blog.csdn.net/wang_yong_hui_1234/article/details/130427887?spm=1001.2014.3001.5501
1.使用overflow属性
Text(
'这是一个很长的文本内容,可能会导致溢出错误。',
overflow: TextOverflow.ellipsis, // 或者 TextOverflow.fade
)
2.使用maxLines属性
Text(
'这是一个很长的文本内容,可能会导致溢出错误。',
maxLines: 2,
)
3.使用Expanded或Flexible
Row(
children: [
Expanded(
child: Text(
'这是一个很长的文本内容,可能会导致溢出错误。',
overflow: TextOverflow.ellipsis,
),
),
],
)
4.使用ListView或SingleChildScrollView
SingleChildScrollView(
child: Text(
'这是一个很长的文本内容,可能会导致溢出错误。',
),
)
有状态(Stateful)Widget:
StatefulWidget
的Widget类,另一个是继承自State
的状态类,状态类包含了Widget的可变状态。示例:
class MyStatefulWidget extends StatefulWidget { @override _MyStatefulWidgetState createState() => _MyStatefulWidgetState(); } class _MyStatefulWidgetState extends State<MyStatefulWidget> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Column( children: <Widget>[ Text('Counter: $_counter'), ElevatedButton( onPressed: _incrementCounter, child: Text('Increment'), ), ], ); } }
无状态(Stateless)Widget:
示例:
class MyStatelessWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('Hello, World!');
}
}
总的来说,有状态Widget适用于需要管理可变状态的场景,而无状态Widget适用于静态内容的展示。使用它们的组合可以有效地构建复杂的用户界面,同时保持性能和可维护性。
路由是用于导航和管理不同页面(或称为屏幕)之间切换的机制。Flutter的路由系统允许您在应用程序中创建多个页面,并实现页面之间的导航。
Flutter中有两种常见的路由:命名路由和普通(非命名)路由
MaterialApp(
routes: {
'/': (context) => HomeScreen(),
'/second': (context) => SecondScreen(),
},
// ...
)
// 导航到命名路由
Navigator.pushNamed(context, '/second');
// 导航到新页面
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
第三方路由框架:
go_router:https://pub.dev/packages?q=go_router
auto_route:https://pub.dev/packages/auto_route
Flutter应用程序通常会包含许多不同的小部件,这些小部件可能需要访问和共享数据,而状态管理的目标是使这个过程更加有组织和高效。
状态管理:
initState
当插入渲染树的时候调用,这个函数在生命周期中只调用一次。这里可以做一些初始化工作,比如初始化State的变量。
didChangeDependencies
在Widget构建后,如果依赖的InheritedWidget发生变化,则会调用此方法。通常用于处理数据依赖关系的变化
didUpdateWidget
当组件的状态改变的时候就会调用didUpdateWidget,比如调用了setState。
deactivate
这通常用于在Widget不再可见或处于非活动状态时执行一些清理工作。
dispose
在Widget从Widget树中移除后,会调用dispose方法,用于释放资源和取消订阅。
Key是一个重要的概念,用于标识Widget并确保它们在Widget树中的唯一性。用于标识和查找Widget。
常用的key:
ValueKey使用:
Widget build(BuildContext context) { return ListView( children: <Widget>[ ListTile( key: ValueKey('item_1'), title: Text('Item 1'), ), ListTile( key: ValueKey('item_2'), title: Text('Item 2'), ), // ... ], ); }
在这个示例中,我们为每个ListTile指定了一个不同的ValueKey,以确保它们在列表中的位置可以被正确标识。
ObjectKey使用
final myObject = MyCustomObject(); // 创建一个自定义对象 Widget build(BuildContext context) { return ListView( children: <Widget>[ ListTile( key: ObjectKey(myObject), // 使用ObjectKey关联自定义对象 title: Text('Item 1'), ), ListTile( key: ObjectKey('some_string'), // 使用ObjectKey关联字符串 title: Text('Item 2'), ), // ... ], ); }
在这个示例中,我们创建了一个自定义对象myObject,并使用ObjectKey将其关联到ListTile上。这意味着当myObject发生变化时,与其关联的ListTile将被认为需要更新。
Dart 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue,另一个叫做“事件队列” event queue。
Future
Future 表示一个可能会在未来完成的操作,通常用于执行一些需要时间的任务,如网络请求、文件读写、计算等。
Future 具有以下几种状态:
try/catch未能够捕获future中的异常,因此future中的异常只能通过catchError()或在then()方法中传入可选参数onError来进行捕获和处理。
相关方法
async/await
如果说Future是一个盒子,当你使用Future直接返回给你个盒子,并且不会阻塞。而async/await就是为了打开这个盒子,拿到执行的结果。
async 和 await 的核心原理是,它们通过暂停和恢复异步函数的执行,使得程序能够继续处理其他任务,而不会被异步操作所阻塞。
1.name??‘默认’
这段代码的含义:当name为空时给个默认值。
2. name!
如果name为空,这段代码会出现什么情况:在debug模式下会显示红色,在release模式下显示一块灰色
3.name?.length
如果 name 为 null,则 length 为 null;否则为 name.length 的值
其实在 Element 的内部有一个 Map<Type, InheritedElement> _inheritedWidgets; 参数,
_inheritedWidgets 一般情况下是空的,只有当父控件是 InheritedWidget 或者本身是 InheritedWidget 时,它才会被初始化,而当父控件是 InheritedWidget 时,这个 Map 会被一级一级往下传递与合并。
Flutter 支持两种集成模式:虚拟显示模式 (Virtual displays) 和混合集成模式 (Hybrid composition)
虚拟显示模式 (Virtual displays)
这种方式使用比较简单:
AndroidView(
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
)
以 Android 为例,Android 上是利用了副屏显示的底层逻辑,使用 VirtualDisplay 类,创建一个虚拟显示器,需要调用 DisplayManager 的 createVirtualDisplay() 方法,将虚拟显示器的内容渲染在一个内存的 Surface 上 ,生成一个唯一的 textureId 。
如下图,之后渲染时将 textureId 传递给 Dart 层,渲染引擎会根据 textureId , 获取到内存里已渲染数据,绘制到 AndroidView 上进行显示。
混合集成模式 (Hybrid composition)
会将原生的 android.view.View 附加到视图层次结构中。因此,键盘处理和无障碍功能是开箱即用的。在 Android 10 之前,此模式可能会大大降低 Flutter UI 的帧吞吐量 (FPS)
相对会比直接使用 AndroidView 在代码上更复杂一点, 需要使用到 PlatformViewLink、 AndroidViewSurface 和 PlatformViewsService 这三个对象
Widget build(BuildContext context) { // This is used in the platform side to register the view. const String viewType = '<platform-view-type>'; // Pass parameters to the platform side. const Map<String, dynamic> creationParams = <String, dynamic>{}; return PlatformViewLink( viewType: viewType, surfaceFactory: (context, controller) { return AndroidViewSurface( controller: controller as AndroidViewController, gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{}, hitTestBehavior: PlatformViewHitTestBehavior.opaque, ); }, onCreatePlatformView: (params) { return PlatformViewsService.initSurfaceAndroidView( id: params.id, viewType: viewType, layoutDirection: TextDirection.ltr, creationParams: creationParams, creationParamsCodec: const StandardMessageCodec(), onFocus: () { params.onFocusChanged(true); }, ) ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated) ..create(); }, ); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。