0%

Flutter 常见问题

经常遇到的几个问题,虽然用了 gpt 可以直接解决,但是还是记录下,也省下了问 gpt 的时间哈。

理解问题

1. flutter stateless 转 stateful

将一个 StatelessWidget 转换为 StatefulWidget 的过程相对简单。以下是一些步骤和示例:

更改 StatelessWidget 继承为 StatefulWidget。
创建一个新的类并继承 State,用于存储状态信息。
将原 StatelessWidget 的 build 方法中的内容移动到新创建的 State 类的 build 方法中。
在新的 StatefulWidget 中覆盖 createState 方法,返回新的 State 类的实例。
下面是一个示例,展示了如何将一个 StatelessWidget 转换为 StatefulWidget:

原始的 StatelessWidget 示例:

import 'package:flutter/material.dart';

class MyStatelessWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text('Hello, I am a StatelessWidget.'),
);
}
}

将 StatelessWidget 转换为 StatefulWidget 示例:

import 'package:flutter/material.dart';

class MyStatefulWidget extends StatefulWidget {
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override
Widget build(BuildContext context) {
return Center(
child: Text('Hello, I am now a StatefulWidget.'),
);
}
}

在上面的示例中,我们首先将 MyStatelessWidget 更改为 MyStatefulWidget 并继承 StatefulWidget。然后,我们创建了一个名为 _MyStatefulWidgetState 的新类,继承自 State 类。接着,我们将原始 StatelessWidget 的 build 方法内容移动到新的 State 类的 build 方法中。最后,我们在新的 StatefulWidget 中覆盖 createState 方法,返回新的 State 类的实例。

2. flutter initstate 不能执行异步方法

  1. AddPostFrameCallback 里执行
  2. 使用 futurebuilder 或者 streambuilder 里执行
- flutter build widget 能不能执行呢
+ build widget 可以执行
- 有没有方法可以在 initstate 和 build widget 之间执行异步方法
+ 这个已经解决了

3. AddPostFrameCallback 没有执行

如下的方法,如果没有执行,多半是 build widget 里没有方法返回 widget 的原因,比如下面的例子,如果没有 return Container(),注意即便时空的 widget 返回也是需要的,那么 AddPostFrameCallback 就不会执行。

WidgetsBinding.Instance.AddPostFrameCallback ((_) {
Print ("WidgetsBinding");
});

UI 问题

listview 里有 container 时候不能设置 container 的宽度

The Container’s width does not reflect inside a Listview in Flutter | Fixed | by Mustafa Tahir | Medium这里给出了解决方案,有几种,原来还没看:

  • 使用 Row 或者 Column 或者 Stack
  • 使用 Unconstrained Box,使用这个是剧中,如果想要对齐还是上面那个可以

listview 控制滚动位置

近日出现一个需求就是,listview 本来展示的一系列内容,会在上一个内容点击之后添加一条新的内容,之前默认滚动到最后就行了;现在要求每次新加的内容都在最上面,也就是说要控制滚动位置。

几个问题:

  1. 使用 setstatus 的方式来控制一个高度,但是这样导致死循环了,增加个变量来控制只执行一次就好了;
  2. 在 list 的底部加一个listview.height - lastItem.height的空 widget,然后滚动到最后不就可以了。因为 flutter 必须是在 widget 渲染之后才能拿到页面的高度,所以在 initstate 里面是拿不到的,所以需要使用 addpostframecallback;
  3. 但是这样的话,每次都会滚动到最后,如果当前的 item 长度超过一个屏幕的话,就会出现问题,所以需要判断一下;
  4. 最后使用 scrollcontroller 来控制滚动位置,也就是显示第二个的时候滚动第一个的高度;
  5. 但是这样的话,如果前两个 item 的高度加起来都不超过一个屏幕的话,就会出现错位问题,因为你拿到的 listview 的 size 并不是想象中的 list 大小区域,这样的话,需要直接用屏幕高度-tabbar高度-底部控件高度来计算,也就是三段式布局的中间部分固定高度,这样就可以了。