-
Flutter_swiper 异步请求显示banner时,初始url为空时 报错问题
主要:没有请求到数据的时候不要设置自动播放。
autoplay: _imageUrls.isNotEmpty
-
可滚动网格布局 品字型布局
参考:
CustomScrollView
组件 -
flutter 子组件占视口100%
参考:
MediaQuery.of(context).size.width,
-
flutter 组件理解
参考:MaterialApp() 相当于 html 的根组件; Scaffold() 相当于 body
-
flutter 组件声明周期
参考官方
-
flutter json解析工具
json_model
的使用主要:
-
[]
和.
运算符,与js
略有不同参考:www.dartcn.com/guides/lang…
主要:
[]
Refers to the value at the specified index in the list。.
Refers to a property of an expression; example:foo.bar
selects propertybar
from expressionfoo
-
点击事件
GestureDetector
范围小主要:behavior: HitTestBehavior.opaque,属性,可以让点击事件透过这个Text的区域。如果不添加这个属性,那么只能点击到文字时才会有响应。
-
路由 带参数返回; Navigator.push 是一个异步操作
参考:参考源码
主要:page1页面需要page2页面返回数据,page1在跳转时需要等待page2返回数据
/// page1 跳转到 page2 Navigator.push( context, MaterialPageRoute( builder: (context) => Page2(params: '来自page1'), ), ).then((data) { /// 关键:这里 data 是page2 中返回的数据 print(data.toString()); }); /// page2 返回 page1 Navigator.pop(context, '来自page2');
-
Widget 声明周期
/// StatefullWidget vs StatelessWidget StatelessWidget:无中间状态变化的widget,需要更新展示内容就得通过重新new,flutter推荐尽量使用StatelessWidget StatefullWidget:存在中间状态变化,那么问题来了,widget不是都immutable的,状态变化存储在哪里?flutter 引入state的类用于存放中间态,通过调用state.setState()进行此节点及以下的整个子树更新 State 生命周期 initState(): state create之后被insert到tree时调用的 didUpdateWidget(newWidget):祖先节点rebuild widget时调用 deactivate():widget被remove的时候调用,一个widget从tree中remove掉,可以在dispose接口被调用前,重新instert到一个新tree中 didChangeDependencies(): 初始化时,在initState()之后立刻调用 当依赖的InheritedWidget rebuild,会触发此接口被调用 build(): After calling [initState]. After calling [didUpdateWidget]. After receiving a call to [setState]. After a dependency of this [State] object changes (e.g., an[InheritedWidget] referenced by the previous [build] changes). After calling [deactivate] and then reinserting the [State] object into the tree at another location. dispose():Widget彻底销毁时调用 reassemble(): hot reload调用 注意事项: A页面push一个新的页面B,A页面的widget树中的所有state会依次调用deactivate(), didUpdateWidget(newWidget)、build()(这里怀疑是bug,A页面push一个新页面,理论上并没有将A页面进行remove操作),当然从功能上,没有看出来有什么异常 当ListView中的item滚动出可显示区域的时候,item会被从树中remove掉,此item子树中所有的state都会被dispose,state记录的数据都会销毁,item滚动回可显示区域时,会重新创建全新的state、element、renderobject 使用hot reload功能时,要特别注意state实例是没有重新创建的,如果该state中存在一下复杂的资源更新需要重新加载才能生效,那么需要在reassemble()添加处理,不然当你使用hot reload时候可能会出现一些意想不到的结果,例如,要将显示本地文件的内容到屏幕上,当你开发过程中,替换了文件中的内容,但是hot reload没有触发重新读取文件内容,页面显示还是原来的旧内容
-
数据自上而下。与双向绑定的区别。
主要:
-
Icons 图标库
-
常用组件:
1. 加载: CircularProgressIndicator 2. 下拉刷新:RefreshIndicator 3. 事件:GestureDetector
-
吸顶滚动的实现方案
主要:
1.SliverPersistentHeade
可配合NestedScrollView
使用参考:
CustomScrollView
的属性shrinkWrap: true,
会改变SliverPersistentHeader
浮动的层级。 -
在 List.map() 中取到index 的方法
参考:stackoverflow.com/questions/5…
主要:有一种
asMap
方法可以将列表转换为映射,其中键是索引,值是索引中的元素。请在这里查看文档。例:List _sample = ['a','b','c']; _sample.asMap().forEach((index, value) => f);
List<Widget> _buildWidgets(List<Object> list) { return list .asMap() .map((index, value) => MapEntry(index, _buildWidget(index, value))) .values .toList(); }
或者,您可以创建一个同步生成器函数以返回一个可迭代
Iterable<MapEntry<int, T>> enumerate<T>(Iterable<T> items) sync* { int index = 0; for (T item in items) { yield MapEntry(index, item); index = index + 1; } } //and use it like this. var list = enumerate([0,1,3]).map((entry) => Text("index: ${entry.key}, value: ${entry.value}"));
-
list 二维展开
主要:
List.expand()
-
网格布局 子元素宽高适配???
-
tabView 缓存问题???
-
通常在用到
PageView
+BottomNavigationBar
或者TabBarView
+TabBar
的时候大家会发现当切换到另一页面的时候, 前一个页面就会被销毁, 再返回前一页时, 页面会被重建, 随之数据会重新加载, 控件会重新渲染 -
键盘弹起导致布局overflow
flutter中关于软键盘弹起导致的问题 当布局高度写死时,例如设置为屏幕高度,这时候键盘弹起页面上会出现布局overflow的提示 软键盘弹起后遮挡输入框 原因:在flutter中,键盘弹起时系统会缩小Scaffold的高度并重建 解决问题1中overflow提示的两种办法: 1)把Scaffold的resizeToAvoidBottomInset属性设置为false,这样在键盘弹出时将不会resize 2)把写死的高度改为 原高度 - MediaQuery.of(context).viewInsets.bottom,键盘弹出时布局将重建,而这个MediaQuery.of(context).viewInsets.bottom变量在键盘弹出前是0,键盘弹起后的就是键盘的高度 解决问题2的办法: 将输入框放进可滚动的Widget中即可,当输入框获取焦点后,系统会自动将它滑动到可视区域
-
TextField 焦点与hint不对齐问题
style: TextStyle( fontSize: 16, textBaseline: TextBaseline.alphabetic, ),
-
ScreenUtil 打 release 包的问题,大概因为ScreenUtil初始化在渲染首页之后,导致界面文字或字体显示不全
主要:两种解决方案
之前有人在官方issue里提过,官方更推荐使用MediaQuery, window获取数据不依赖Widget的生命周期,这就会产生一些问题,例如使用debug版本因为程序运行缓慢而拿到宽高数据,而release版本应用速度提升后就无法获取。我现在是在iniState中使用SchedulerBinding.instance.addPostFrameCallback()的回调进行初始化,希望对您有帮助。
@hzysunrain 我试过在didChangeMetrics中初始化ScreenUtil , 但是它的触发时间晚于build (在我尝试的几次) 哪怕我在Myapp中的didChangeMetrics都要在home的build方法之后才调用 比较理想的就是在home(一般作为启动页面)中初始化 , 但是不使用ScreenUtil(避免特殊情况拿不到屏幕数据), 在启动页的下一个页面应该就可以直接使用了
23.使用SingleChildScrollView和Column可以使页面滚动,Column中有ListView时,为使ListView滚动和页面滚动不冲突,可设置ListView的physics为NeverScrollableScrollPhysics,SingleChildScrollView的physics为AlwaysScrollableScrollPhysics。
24.ListView,GridView,TabBarView等Widget都没有自己的高度,必须指定父组件高度,若在Column中想设置动态高度可用Expanded嵌套。