Link-Fight / Link-Fight.github.io

Link_Fight博客
5 stars 0 forks source link

flutter 开坑 #35

Open Link-Fight opened 5 years ago

Link-Fight commented 5 years ago

Weight

SnackBar / of

文档介绍,它是一个在底部提示的小组件。 调用代码是:

Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('请先登录'),
));              

一跑,炸了

I/flutter (23462): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
I/flutter (23462): The following assertion was thrown while handling a gesture:
I/flutter (23462): Scaffold.of() called with a context that does not contain a Scaffold.
I/flutter (23462): No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This
I/flutter (23462): usually happens when the context provided is from the same StatefulWidget as that whose build
I/flutter (23462): function actually creates the Scaffold widget being sought.
I/flutter (23462): There are several ways to avoid this problem. The simplest is to use a Builder to get a context that
I/flutter (23462): is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of():
I/flutter (23462):   https://api.flutter.dev/flutter/material/Scaffold/of.html
I/flutter (23462): A more efficient solution is to split your build function into several widgets. This introduces a
I/flutter (23462): new context from which you can obtain the Scaffold. In this solution, you would have an outer widget
I/flutter (23462): that creates the Scaffold populated by instances of your new inner widgets, and then in these inner
I/flutter (23462): widgets you would use Scaffold.of().
I/flutter (23462): A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the
I/flutter (23462): key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function.
I/flutter (23462): The context used was:
I/flutter (23462):   MyHomePage(state: _MyHomePageState#42b0e)
I/flutter (23462):
I/flutter (23462): When the exception was thrown, this was the stack:

按照提示报错原因是 Scaffold.of() called with a context that does not contain a Scaffold. No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). usually happens when the context provided is from the same StatefulWidget as that whose build function actually creates the Scaffold widget being sought.

通常发生在StatefulWidget组件内(我的刚好是)

解决方案有:

1: The simplest is to use a Builder to get a context that is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of(): https://api.flutter.dev/flutter/material/Scaffold/of.html

2: A more efficient solution is to split your build function into several widgets. This introduces a new context from which you can obtain the Scaffold. In this solution, you would have an outer widget that creates the Scaffold populated by instances of your new inner widgets, and then in these inner widgets you would use Scaffold.of().

3:A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function.

我采用的是第一种方案[1],Create an inner BuildContext

Builder(
      // Create an inner BuildContext so that the onPressed methods
      // can refer to the Scaffold with Scaffold.of().
      builder: (BuildContext context) {
        return Card(
            child: ListTile(
          leading: Icon(Icons.input),
          title: title,
          onTap: () {
            if (userInfo == null) {
              Scaffold.of(context).showSnackBar(SnackBar(
                  content: content,
              ));
            } else {
              _getWarehouseTransferList();
            }
          },
        ));
      },
    );

picture-using-camera

按照demo的代码,来跑时候。显示遇到flutter_testpath包的依赖冲突,把path锁定到1.6.2后解决。

在真机调试中,先报出jar包下载失败,这翻墙以及切换了不同的线路后,解决。 image

接着又遇到报错: image 意思就是camera包支持的sdk:minSdkVersion,比项目支持的sdk:minSdkVersion要高。我采取的解决方案是提高项目的sdk:minSdkVersion, 打开文件./android/app/build.gradle,把原来minSdkVersion 16改为minSdkVersion 21即可。

Link-Fight commented 5 years ago

Why StatefulWidget and State are separate objects?

You might wonder why StatefulWidget and State are separate objects. In Flutter, these two types of objects have different life cycles. Widgets are temporary objects, used to construct a presentation of the application in its current state. State objects, on the other hand, are persistent between calls to build(), allowing them to remember information.

不同于StatelessWidget ,在使用StatefulWidget时候,需要额外写个对于的State,并且要独立分开写。这样做的原因是,这两个对象有着不一样的生命周期。Widgets存在时间比较短暂,可以认为是State某一个状态的表现,一旦State改变了,Widgets就要重新创建。而State就要持久些,因为它要记住状态。

Link-Fight commented 5 years ago

不通过BuildContent来实现导航

Navigate without a BuildContext in Flutter | Code Guide Flutter | 使用 ServiceLocator 实现无 context 导航

Link-Fight commented 5 years ago

获取dart中的数据类型

getTypeName(dynamic obj) {
  return reflect(obj).type.reflectedType.toString();
}
Link-Fight commented 5 years ago

JSON与字符串的相互转化

使用 dart:convert中的 jsonEncodejsonDecode 方法。

使用toString()方法能将对象转换成字符串,但是会丢失引号等信息,不再是标准JSON,导致服务端解析不正常

Link-Fight commented 5 years ago

支持AndroidX

使用的flutter版本是1.10.15-pre.163,在build 项目时候,DEBUG CONSOlE提示 Your app isn't using AndroidX.。就是提示要升级到AndroidX:

Google 2018 IO 大会推出了 Android新的扩展库 AndroidX,用于替换原来的 Android扩展库,将原来的android.替换成androidx.;只有包名和Maven工件名受到影响,原来的类名,方法名和字段名不会更改。接下来我们来看看使用 AndroidX的扩展库需要哪些配置

它这个提示我一直没怎么理,直到我要使用 camera 0.5.6+1,直接就是报error了:

Launching lib\main.dart on MI 6 in debug mode... [!] Your app isn't using AndroidX. To avoid potential build failures, you can quickly migrate your app by following the steps on https://goo.gl/CP92wY.

FAILURE: Build failed with an exception.

BUILD FAILED in 3s AndroidX incompatibilities may have caused this build to fail. Please migrate your app to AndroidX. See https://goo.gl/CP92wY.

现在看来路有两条了: 1 看看怎么升级到AndroidX:这个百度,谷歌千百遍,发现flutter官网就有 AndroidX Migration,不过要使用android studio。 2 查看插件cameraChangelog,发现0.2.9+1版本没有升级到AndroidX,可以使用这个。

迁移到AndroidX后,还是有些手尾问题: 就是要项目中一个库,但是有两个版本的依赖,要选择使用哪个。 按照这个博客的提示解决了 image