超过百万的* Flutter 问题
老孟导读:今天分享*上高访问量的20大问题,这些问题给我一种特别熟悉的感觉,我想你一定或多或少的遇到过,有的问题在*上有几十万的阅读量,说明很多人都遇到了这些问题,把这些问题整理分享给大家,每期20个,每隔2周分享一次。
如何实现android平台的wrap_content 和match_parent
你可以按照如下方式实现:
1、width = wrap_content height=wrap_content:
wrap( children: <widget>[your_child])
2、width = match_parent height=match_parent:
container( height: double.infinity, width: double.infinity,child:your_child)
3、width = match_parent ,height = wrap_conten:
row( mainaxissize: mainaxissize.max, children: <widget>[*your_child*], );
4、width = wrap_content ,height = match_parent:
column( mainaxissize: mainaxissize.max, children: <widget>[your_child], );
如何避免futurebuilder频繁执行future
方法
错误用法:
@override widget build(buildcontext context) { return futurebuilder( future: httpcall(), builder: (context, snapshot) { }, ); }
正确用法:
class _examplestate extends state<example> { future<int> future; @override void initstate() { future = future.value(42); super.initstate(); } @override widget build(buildcontext context) { return futurebuilder( future: future, builder: (context, snapshot) { }, ); } }
底部导航切换导致重建问题
在使用底部导航时经常会使用如下写法:
widget _currentbody; @override widget build(buildcontext context) { return scaffold( body: _currentbody, bottomnavigationbar: bottomnavigationbar( items: <bottomnavigationbaritem>[ ... ], ontap: (index) { _bottomnavigationchange(index); }, ), ); } _bottomnavigationchange(int index) { switch (index) { case 0: _currentbody = onepage(); break; case 1: _currentbody = twopage(); break; case 2: _currentbody = threepage(); break; } setstate(() {}); }
此用法导致每次切换时都会重建页面。
解决办法,使用indexedstack
:
int _currindex; @override widget build(buildcontext context) { return scaffold( body: indexedstack( index: _currindex, children: <widget>[onepage(), twopage(), threepage()], ), bottomnavigationbar: bottomnavigationbar( items: <bottomnavigationbaritem>[ ... ], ontap: (index) { _bottomnavigationchange(index); }, ), ); } _bottomnavigationchange(int index) { setstate(() { _currindex = index; }); }
tabbar切换导致重建(build)问题
通常情况下,使用tabbarview如下:
tabbarview( controller: this._tabcontroller, children: <widget>[ _buildtabview1(), _buildtabview2(), ], )
此时切换tab时,页面会重建,解决方法设置pagestoragekey
:
var _newskey = pagestoragekey('news'); var _technologykey = pagestoragekey('technology'); tabbarview( controller: this._tabcontroller, children: <widget>[ _buildtabview1(_newskey), _buildtabview2(_technologykey), ], )
stack 子组件设置了宽高不起作用
在stack中设置100x100红色盒子,如下:
center( child: container( height: 300, width: 300, color: colors.blue, child: stack( children: <widget>[ positioned.fill( child: container( height: 100, width: 100, color: colors.red, ), ) ], ), ), )
此时红色盒子充满父组件,解决办法,给红色盒子组件包裹center、align或者unconstrainedbox,代码如下:
positioned.fill( child: align( child: container( height: 100, width: 100, color: colors.red, ), ), )
如何在state类中获取statefulwidget控件的属性
class test extends statefulwidget { test({this.data}); final int data; @override state<statefulwidget> createstate() => _teststate(); } class _teststate extends state<test>{ }
如下,如何在_teststate获取到test的data
数据呢:
- 在_teststate也定义同样的参数,此方式比较麻烦,不推荐。
- 直接使用
widget.data
(推荐)。
default value of optional parameter must be constant
上面的异常在类构造函数的时候会经常遇见,如下面的代码就会出现此异常:
class barrageitem extends statefulwidget { barrageitem( { this.text, this.duration = duration(seconds: 3)});
异常信息提示:可选参数必须为常量,修改如下:
const duration _kduration = duration(seconds: 3); class barrageitem extends statefulwidget { barrageitem( {this.text, this.duration = _kduration});
定义一个常量,dart
中常量通常使用k
开头,_
表示私有,只能在当前包内使用,别问我为什么如此命名,问就是源代码中就是如此命名的。
如何移除debug模式下右上角“debug”标识
materialapp( debugshowcheckedmodebanner: false )
如何使用16进制的颜色值
下面的用法是无法显示颜色的:
color(0xb74093)
因为color的构造函数是argb
,所以需要加上透明度,正确用法:
color(0xffb74093)
ff
表示完全不透明。
如何改变应用程序的icon和名称
链接:
如何给textfield设置初始值
class _foostate extends state<foo> { texteditingcontroller _controller; @override void initstate() { super.initstate(); _controller = new texteditingcontroller(text: '初始值'); } @override widget build(buildcontext context) { return textfield( controller: _controller, ); } }
scaffold.of() called with a context that does not contain a scaffold
scaffold.of()中的context没有包含在scaffold中,如下代码就会报此异常:
class homepage extends statelesswidget { @override widget build(buildcontext context) { return scaffold( appbar: appbar( title: text('老孟'), ), body: center( child: raisedbutton( color: colors.pink, textcolor: colors.white, onpressed: _displaysnackbar(context), child: text('show snackbar'), ), ), ); } } _displaysnackbar(buildcontext context) { final snackbar = snackbar(content: text('老孟')); scaffold.of(context).showsnackbar(snackbar); }
注意此时的context是homepage的,homepage并没有包含在scaffold中,所以并不是调用在scaffold中就可以,而是看context,修改如下:
_scaffoldkey.currentstate.showsnackbar(snackbar);
或者:
scaffold( appbar: appbar( title: text('老孟'), ), body: builder( builder: (context) => center( child: raisedbutton( color: colors.pink, textcolor: colors.white, onpressed: () => _displaysnackbar(context), child: text('老孟'), ), ), ), );
waiting for another flutter command to release the startup lock
在执行flutter
命令时经常遇到上面的问题,
解决办法一:
1、mac或者linux在终端执行如下命令:
killall -9 dart
2、window执行如下命令:
taskkill /f /im dart.exe
解决办法二:
删除flutter sdk的目录下/bin/cache/lockfile
文件。
无法调用setstate
不能在statelesswidget控件中调用了,需要在statefulwidget中调用。
设置当前控件大小为父控件大小的百分比
1、使用fractionallysizedbox
控件
2、获取父控件的大小并乘以百分比:
mediaquery.of(context).size.width * 0.5
row直接包裹textfield异常:boxconstraints forces an infinite width
解决方法:
row( children: <widget>[ flexible( child: new textfield(), ), ], ),
textfield 动态获取焦点和失去焦点
获取焦点:
focusscope.of(context).requestfocus(_focusnode);
_focusnode
为textfield的focusnode:
_focusnode = focusnode(); textfield( focusnode: _focusnode, ... )
失去焦点:
_focusnode.unfocus();
如何判断当前平台
import 'dart:io' show platform; if (platform.isandroid) { // android-specific code } else if (platform.isios) { // ios-specific code }
平台类型包括:
platform.isandroid platform.isfuchsia platform.isios platform.islinux platform.ismacos platform.iswindows
android无法访问http
其实这本身不是flutter的问题,但在开发中经常遇到,在android pie版本及以上和ios 系统上默认禁止访问http,主要是为了安全考虑。
android解决办法:
在./android/app/src/main/androidmanifest.xml
配置文件中application标签里面设置networksecurityconfig属性:
<?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:networksecurityconfig="@xml/network_security_config"> <!-- ... --> </application> </manifest>
在./android/app/src/main/res
目录下创建xml文件夹(已存在不用创建),在xml文件夹下创建network_security_config.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartexttrafficpermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config> </network-security-config>
ios无法访问http
在./ios/runner/info.plist
文件中添加如下:
<?xml version="1.0" encoding="utf-8"?> <!doctype plist public "-//apple//dtd plist 1.0//en" "http://www.apple.com/dtds/propertylist-1.0.dtd"> <plist version="1.0"> <dict> ... <key>nsapptransportsecurity</key> <dict> <key>nsallowsarbitraryloads</key> <true/> </dict> </dict> </plist>
交流
github地址:
170+组件详细用法:
如果你对flutter还有疑问或者技术方面的疑惑,欢迎加入flutter交流群(微信:laomengit)。
同时也欢迎关注我的flutter公众号【老孟程序员】,公众号首发flutter的相关内容。
flutter生态建设离不开你我他,需要大家共同的努力,点赞也是其中的一种,如果文章帮助到了你,希望点个赞。
推荐阅读
-
关于超过255台电脑的内网IP规划问题
-
Android Multidex使用,方法数超过“65536”问题的解决方式
-
android TextView多行文本(超过3行)使用ellipsize属性无效问题的解决方法
-
怎样解决asp.net上传文件超过了最大请求长度的问题
-
Flutter 使用插件permission_handler的一些问题
-
使用TamperMonkey解决Google被墙*无法正常使用的问题
-
一个关于struts2上传文件超过限制大小如何提示的问题
-
Flutter 解答*问题Page value is only available after content dimensions are established
-
一个关于struts2上传文件超过限制大小如何提示的问题
-
超过百万的* Flutter 问题