Flutter从入门到写出完整App Day16

20.4.6 一

今天内容还是比较多的
项目里还有什么东西没有做?
菜谱详情页面
过滤页面, 过滤掉一些食物
右滑出的菜单页面
收藏显示

菜谱详情页面
两个地方都会使用
局部变量传递来传递去

图片
食材
制作步骤
超过了屏幕的高度, 滚动
方案非常多, 滚动的东西不是相同的

Column超过屏幕高度, 报错超过安全区域
如何解决?SingleChildScrollView
Column作为子widget
知识点补充

先把代码划分清晰, 用Text占位, 之后进行填充

  1. 横幅图片 Widget buildBannerImage() {}
    Image包裹一个Container

  2. 制作材料 Widget buildMakeMaterial() {}
    小标题, 内容
    两个标题长得差不多
    两种处理方式: 单独封装一个Widget/抽成一个公共的方法
    Widget buildMakeTitle() {}
    上下有一定的间距, 包裹Container
    通过Theme去拿, 需要把上下文传到方法里
    设置垂直方向的padding
    希望是粗体 -> copyWith()
    分析: 搞一个ListView来做
    Column嵌套ListView会出现一个常见的问题

有一个边框
Container里面放一个ListView
用Card做出来的东西比较好看

重点!!!
跑一下就报错
Flutter中非常经典的一个错误 hasSize
错误产生的原因
把所有Widget放在一个Column里面, 最大占据控件, 屏幕的高度
SingleChildScrollView只是让内容可以滚动而已
Column需要有一个固定的高度
放了一个ListView后出问题, ListView很特别, 滚动方向上尽可能大的占据空间, 自己也不知道占据多少空间
Container的高度是300
里面放个ListView, 尽可能占据大空间 => 只能占据300
Column的特点, 需要所有子Widget有个明确的高度,
有了明确的高度才能知道如何摆放, mainAxisAligment
产生了矛盾, ListView希望尽可能多的占据高度, Column希望ListView给一个固定的高度
Column里面放了一个ListView/ListView中放一个ListView
hasSize: 子Widget不能有一个明确的高度, 父Widget希望子Widget有个明确的高度

给Container一个明确的高度300, 会产生另一个问题
ListView的高度可能会超过300, ListView可以在Container里面滚动, 没有超过也可以滚动
出现局部滚动的效果
现在不要局部滚动
高度不能写死, 内容多高, 撑多高

如何解决?
让ListView有一个固定的高度, 不是尽量多的占据高度
=> 一个属性shrinkWrap: 范围内进行包裹, 默认false
单独拖动的时候可以进行滚动
=> 一个属性physics: NeverScrollableScrollPhysics(),设置不能滚动
每一个cell本来就存在的内边距设置为0

距离边缘太近, 给Container一个固定的宽度或者
媒体查询 MediaQuery 左右两边各有15

  1. 制作步骤 Widget buildMakeSteps() {}
    Container里面搞个ListView
    和上面制作材料相似的地方
    Widget buildMakeContent(BuildContext context, Widget child) {}
    间的的重构
    共享一个外面的Container, 传入child
    比较好看 => 写成可选参数,

圆形的步骤编号
圆角文字, 类似于圆角图片
leading: CircleAvatar(
child: Text()
)
背景默认情况下用导航栏颜色
也可以单独设置 backgroundColor: Orange
很多好用的Widget
学会去搜索, 最好用英文用Google搜索StackOverFlow

底部空间去除 EdgeInsets.zero

和制作材料是重复代码
搞个Widget继承ListView, 有些重复的东西写死

收藏按钮
FloatingActionButton
改了主题, 需要重新跑一下
监听点击
布局需要多练

不适合用Column, 尽可能大, 循环创建

Flutter的定位
做一个成套的东西, 最开始不想调用原生
原来的App是用原生开发的全线转向Flutter成本高, 模块开发
混合开发
Flutter的第三方插件在越来越丰富
开源出去的机会
Web端如果也发展的比较好的话, 很看好
混合开发会讲, 桥梁, 原理, 知道为什么要这样写
开源的, 读源码, 里面有很多东西

收藏的功能
共享收藏过哪些东西
多个地方使用共享
状态的共享
有几种做法

  1. 单独搞一个Provider, 记录着所有的收藏, 继续收藏继续添加
    相当于在搞一个ViewModel
  2. 给每一个食物添加一个属性, isFavor属性, 默认false
    点击了某个食物, 设置为true, 刷新界面setState
    考虑一个问题, 采用第二个方案, 需要改StatelessWidget为StatefulWidget
    选择第一种方案, 统一的管理, 数组添加移除

favor_view_model.dart
class JHFavorViewModel extends ChangeNotifier {}
操作方法
void addMeal(JHMealModel meal) {}
void removeMeal(JHMealModel meal) {}
操作后发出通知 notifyListeners()
搞一个车方法返账bool
bool isFavor(JHMealModel meal) {
return
}

detail.dart中

添加floatingActionButton: Consumer(

    return ;
)
  1. 判断是否是收藏状态
    final iconData = favorVM.isFavor(meal) ? Icons.favorite : Icons.favorite_border;
    final iconColor = favorVM. ? Colors.red : Colors.black;
    写的过程中进行重构
    报错, 找不到Provider
    main.dart中改东西
    providers: [
    多个Provider
    ],

布局的一个问题
Column交叉轴上确实是个Center
默认占据的宽度不是整个屏幕的宽度
是最大的子Widget的宽度
有图片加载完后, 图片会撑大宽度
不能直接设置宽度, 给里面的一个Widget设置一个尽可能大的宽度infinity
遇到问题分析问题

再次点击收藏按钮判断进行收藏或者取消操作
if判断其他地方可能也需要使用
在favor_view_model.dart中
void handleMeal(JHMealModel meal) {}

detail_floating_button.dart
JHDetailFloatingButton
detail.dart就比较简洁了

菜谱列表页的收藏
之前是直接写死的
之前封装的Widget里面
meal_item.dart
很多东西需要做一个改变
搞一个方法

Widget buildFavorItem() {}
Consumer(
    builder: (ctx, favorVM, child) {
        //1. 判断时候收藏状态
        final iconData = favorVM.isFavor(_meal) ? Icons.favorite :
        final iconColor = ...
        final title = favorVM.isFavor(_meal) ? "收藏" : "未收藏";

        return JHOperationItem(Icon(iconData, color: iconColor,), title);
    }
)

可选参数的名字不能以下划线开头
operation_item.dart修改

监听点击GestureDetector(child:JHOperationItem())
文字的长度发生改变的世邦, 其他会一起变

  1. 给收藏按钮一个确定的宽度
  2. 文本长度改成一样 未收藏 已收藏
    Row里面Space
    一开始给一个固定的宽度
    operation_item.dart中给一个固定的宽度, 要写成.px
    很容易点到旁边, 给包裹一个padding, 让收藏按钮的高度增大
    开发中的常见做法, 返回按钮的点击区域

favor.dart
创建favor_content.dart
JHFavorContent
拿到数据, 展示列表
没有收藏时空的判断处理

另一个方案, 模型中搞个isFavor, 可以自己尝试一下

再讲一个知识点
抽屉效果
Flutter里面实现起来非常的简单
添加到首页, 导航栏抽屉图标
home.dart
drawer: Drawer()
默认情况下有一定的宽度
包裹一个Container, 调整宽度

如何改首页导航栏上抽屉的图标?
appBar中
leading: Icon(Icons.setting)
直接改了以后Drawer不弹出来了
遇到问题自己搜索
谷歌flutter drawer icon
不能搞一个Icon => IconButton(icon: Icon(Icons.build), onPressed: () {})
怎么弹出?
Navigator.of(context).openDrawer();
依然不可以
解决思路, 自己学习方法
Scaffold上下文拿到的不一样
如何处理?
leading: Builder(
builder: (ctx) {
return IconButton
}
)

抽屉里面的东西做一下
再做一个封装
AppBar也做一个封装
home_app_bar.dart
JHHomeAppBar : super中写
home_drawer.dart
JHHomeDrawer
child: Drawer(
child: Column
)

Widget buildHeaderView() {}
alignment: Alignment(0, 0.5)
增加一个超大字体主题, 需要重新跑一下, 字体比较细, 需要加粗

进餐、过了
Widget buildListTile(Widget icon, String title) {}
弹出Drawer
点击传入函数
Navigator.of(context).pop()

过滤下节课来说

你可能感兴趣的:(Flutter从入门到写出完整App Day16)