在理解这些问题之前,建议看一下Flutter架构原理,如下链接:
目录
-
- 一. 有个Text节点,由于文字内容过多,发生了溢出错误,该如何解决?
- 二.Widget、Element、RenderObject三者之间的关系?
- 三.什么是有状态(Stateful)和无状态(Stateless)Widget?它们之间有什么区别?
- 四.Flutter中的路由是什么?如何导航到新的页面?
- 五.什么是Flutter的状态管理?有哪些状态管理库可用?
- 六.请解释Flutter的Widget生命周期
- 七.什么是Flutter的Key?它们的作用是什么?
- 八.Dart是单线程模型,如何运行的?
- 九.var、final、const、late介绍
- 十.Future,Steam,async,await 区别和原理?
- 十一.空检查问题
- 十二.InheritedWidget如何实现共享的
- 十三.Flutter如何支持原生View的
- 一. 有个Text节点,由于文字内容过多,发生了溢出错误,该如何解决?
一. 有个Text节点,由于文字内容过多,发生了溢出错误,该如何解决?
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(
'这是一个很长的文本内容,可能会导致溢出错误。',
),
)
二.Widget、Element、RenderObject三者之间的关系?
- Widget是UI的声明式描述,它们通常是层次结构的顶部。
- Element是Widget的实例,它们构成了渲染树,并管理了Widget的生命周期和状态。
- RenderObject是渲染树的实际工作单位,负责执行实际的绘制和布局。
三.什么是有状态(Stateful)和无状态(Stateless)Widget?它们之间有什么区别?
-
有状态(Stateful)Widget:
-
有状态Widget是一种可以包含可变状态的Widget类型。
-
当其内部状态(state)发生变化时,可以通知Flutter框架进行重新构建,并且可以在多次构建之间保留状态。
-
通常在需要响应用户交互或数据更新时使用,比如表单、按钮、动画等。
-
有状态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:
-
无状态Widget是一种不包含可变状态的Widget类型。
-
它们通常用于展示静态内容或不需要重新构建的部分,因为它们在构建后不会发生变化。
-
无状态Widget是不可变的,一旦构建就不能再修改内部状态。
-
通常用于构建UI的静态部分,以提高性能。示例:
-
class MyStatelessWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('Hello, World!');
}
}
总的来说,有状态Widget适用于需要管理可变状态的场景,而无状态Widget适用于静态内容的展示。使用它们的组合可以有效地构建复杂的用户界面,同时保持性能和可维护性。
四.Flutter中的路由是什么?如何导航到新的页面?
路由是用于导航和管理不同页面(或称为屏幕)之间切换的机制。Flutter的路由系统允许您在应用程序中创建多个页面,并实现页面之间的导航。
Flutter中有两种常见的路由:命名路由和普通(非命名)路由
MaterialApp(
routes: {
'/': (context) => HomeScreen(),
'/second': (context) => SecondScreen(),
},
// ...
)
// 导航到命名路由
Navigator.pushNamed(context, '/second');
// 导航到新页面
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
第三方路由框架:
go_router:pub.dev/packages?q=…
auto_route:pub.dev/packages/au…
五.什么是Flutter的状态管理?有哪些状态管理库可用?
Flutter应用程序通常会包含许多不同的小部件,这些小部件可能需要访问和共享数据,而状态管理的目标是使这个过程更加有组织和高效。
状态管理:
- InheritedWidget:InheritedWidget是Flutter框架提供的一种状态共享机制。它允许您在小部件树中共享数据,以便子小部件可以轻松访问共享状态。这在跨多个小部件传递数据时非常有用。
- Provider:Provider是一个开源的Flutter状态管理库,它建立在InheritedWidget之上,并提供了更简化的数据共享和更新方式。它通常与Consumer小部件一起使用,以便小部件只在相关数据发生变化时重新构建。
- flutter_bloc :它提供了用于实现BLoC设计模式的工具和类,提供了一种清晰、可测试和可维护的方式来管理Flutter应用程序的状态和业务逻辑。它将状态与UI分离,使得应用程序更易于扩展和修改
六.请解释Flutter的Widget生命周期
initState
当插入渲染树的时候调用,这个函数在生命周期中只调用一次。这里可以做一些初始化工作,比如初始化State的变量。
didChangeDependencies
在Widget构建后,如果依赖的InheritedWidget发生变化,则会调用此方法。通常用于处理数据依赖关系的变化
didUpdateWidget
当组件的状态改变的时候就会调用didUpdateWidget,比如调用了setState。
deactivate
这通常用于在Widget不再可见或处于非活动状态时执行一些清理工作。
dispose
在Widget从Widget树中移除后,会调用dispose方法,用于释放资源和取消订阅。
七.什么是Flutter的Key?它们的作用是什么?
Key是一个重要的概念,用于标识Widget并确保它们在Widget树中的唯一性。用于标识和查找Widget。
常用的key:
- ValueKey: 通过一个特定的值作为标识。
- ObjectKey: 通过一个对象作为标识。
- GlobalKey: 全局标识,通常用于跨Widget树中的状态共享。
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是单线程模型,如何运行的?
Dart 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue,另一个叫做“事件队列” event queue。
九.var、final、const、late介绍
- var: 定义的变量会自动推断类型,如果没有初始化,那么它的值是nil。在声明时赋值,相当于确定了类型。
- final: 可以先声明再次赋值,但是只能赋值一次
- const: 修饰常量,声明的时候就得赋值
- late: 延迟初始化变量,如果这个变量没有被使用的话就不会被初始化。
十.Future,Steam,async,await 区别和原理?
Future
Future 表示一个可能会在未来完成的操作,通常用于执行一些需要时间的任务,如网络请求、文件读写、计算等。
最后
为了方便有学习需要的朋友,我把资料都整理成了视频教程(实际上比预期多花了不少精力),由于篇幅有限,都放在了我的GitHub上,点击即可免费获取!
Androidndroid架构视频+BAT面试专题PDF+学习笔记
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
- 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!
- 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,没有人能随随便便成功。
加油,共勉。