有关Flutter的学习碎片

环境:vscode+android studio

碎片

1.appbar了解

2.消息提示库Fluttertoast(非官方)

依赖引入,具体页面使用

//pubspec.yaml
dependencies:
  fluttertoast: ^8.2.5
//..具体页面
import 'package:fluttertoast/fluttertoast.dart';
//自定义方法
// 请求响应信息  0 成功 1 失败 
  void showToast(int flag) {
    Fluttertoast.showToast(
      msg: (flag == 0) ? "操作成功" : "操作失败!",
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.BOTTOM,
      backgroundColor: (flag == 0)
          ? Color.fromRGBO(231, 250, 240, 1)
          : Color.fromRGBO(255, 237, 237, 1),
      textColor: (flag == 0)
          ? Color.fromRGBO(113, 226, 163, 1)
          : Color.fromRGBO(255, 73, 73, 1),
      fontSize: 16.0,
    );
  }

3.RefreshIndicator用于可滚动组件下拉刷新数据

注:需要确保_refreshIndicatorKey.currentState.show() 方法能够正常调用,Container就不行

 //刷新页面 调用的方法
child: RefreshIndicator(
      onRefresh: () {
       return _getList(); // myRefreshFunction是一个返回Future<void>的函数
},
//需要确保这俩都是可下拉的组件
child: total!=0?_buildGrid():  _nullShow()))),

4.有关变量初始化

flutter 在使用未初始化的变量是会报错,所以要在使用前初始化,声明时可用late告诉flutter之后再进行初始化。

5.有关对项目文件及.apk安装后文件的操作:

(1)项目变成.apk安装后其内部(.apk)的文件为只读,不能进行修改,只能进行读操作,该类文件一般需要在pubspec.yaml文件进行声明后才会被打包进包里

//读取项目内pubspec.yaml声明的文件中的内容
try {
    final String content =
        await rootBundle.loadString('assets/secretkey/31010');
    if (content.isEmpty) {
      return false; // 文件为空
    }
    return true; // 文件没找到
  } catch (e) {
    return false; // 没找到/发生错误
  }

(2)在安装完应用程序后会有一个私有存储空间,用来存一些动态可编辑的文件,其来源通常有:

由应用程序内部资源文件生成,应用程序内部资源复制的文件,运行时动态创建或下载的文件,用户产生的数据...

私有存储空间在程序安装到设备时创建,在卸载时销毁,运行时可对其中文件进行读写

6.有关横竖屏适配:

有时候横屏竖屏ui因为种种原因可能会导致显示异常,有两种解决方案

(1)横/竖屏适配

 //横竖屏适配true为横屏,false为竖屏
    bool screenstatusflag = true;
    //获取屏幕状态
    MediaQuery.of(context).size.width >
            MediaQuery.of(context).size.height 
        ? screenstatusflag= true  //横屏
        : screenstatusflag= false;// 竖屏
    // 使用 MediaQuery 获取设备宽高
final double deviceWidth = MediaQuery.of(context).size.width;
 final double deviceHeight = MediaQuery.of(context).size.height;
......
 height: screenstatusflag? 500 : deviceHeight * 0.27,
 width:screenstatusflag? 900 : deviceWidth * 0.82,
......
Container(
  height: screenstatusflag? 500 :deviceHeight * 0.27,
  width:screenstatusflag? 590 : deviceWidth * 0.49,
  child: Image.asset(
     'assets/img/login.png',
      fit: BoxFit.contain,
),

2.横/竖屏锁定(强制横/竖屏)

 // 强制横屏
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight
  ]);
// 强制竖屏
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown
  ]);

问题

1.状态栏颜色设置

设置appbar背景颜色是连同状态栏颜色一起设置了

解决过程:

在初始化方法中调用该方法  会被覆盖,只有一瞬间有变化,后又变回来

正确解决:在appbar中添加

systemOverlayStyle: SystemUiOverlayStyle(
            statusBarColor: Colors.red, // 设置状态栏的颜色
          ),

结果:

2.展示图片

在和lib同目录下创建存图片的文件夹

在pubspec.yaml文件设置存图片文件路径,注意空格

在需要的地方导入,搞完之后重启项目

3.修改对话框在键盘弹出时对话框变形

原因:

解决:使用ListView

4.

展开后下拉框挤到对话框边缘,且方角难看

尝试:

(1)

直接在DropdownButtonFormField外套Container改不受影响  

(2)尝试在items返回的值中套Container

items: departmentList .map<DropdownMenuItem<String>>((dynamic value) {
                                            return DropdownMenuItem<String>(
                                              value: value,
                                              child: Container(
                                                decoration: BoxDecoration(
                                                  color: Colors
                                                      .blueAccent, // 设置单元格的背景颜色
                                                  borderRadius:
                                                      BorderRadius.circular(
                                                          12), // 设置圆角
                                                ),
                                                width: 100, // 设置宽度为200
                                                height: 60, // 设置高度为50
                                                child: Text(
                                                  value,
                                                  style: TextStyle(
                                                      color: Colors.black),
                                                ),
                                              ),
                                            );
                                          })
                                          .toSet()
                                          .toList(),

改后

(3)尝试更换PopupMenuButton作为下拉框

PopupMenuButton( onSelected: (String newValue) {
                                            setState(() {
                                              dropdownValue = newValue;
                                              print(
                                                  'dropdownValue被更改$dropdownValue');
                                              // department = newValue;
                                            });
                                          },
                                             itemBuilder: (BuildContext context) {
                                            return departmentList
                                                .map((dynamic value) {
                                              return PopupMenuItem<String>(
                                                value: value,
                                                child: Container(
                                                  decoration: BoxDecoration(
                                                    // color: Colors
                                                    //     .blueAccent, 
                                                    borderRadius:
                                                        BorderRadius.circular(
                                                            18), // 设置圆角
                                                  ),
                                                  width: 100, // 设置宽度为200
                                                  height: 40, // 设置高度为50
                                                  child: Container(
                                                    height: 50,
                                                    width: 100,
                                                    child: Text(
                                                      value,
                                                      style: TextStyle(
                                                          color: Colors.black),
                                                    ),
                                                  ),
                                                ),
                                              );
                                            }).toList();
                                          },
                                          child: Text('科室: $dropdownValue'),
                                                // Icon(Icons.arrow_drop_down),
                                        )

发现更改下拉框值后,默认展示值没变..

导致原因没查出来

(4)尝试用SizeBox+DropdownMenu替换

 SizedBox(width: 100, // 设置宽度为300
                                    height: 50, // 设置高度为150
                                    child:
                                        DropdownMenu<String>(
                                      width: 300,
                                      menuHeight: 150,
                                      initialSelection: dropdownValue,
                                      onSelected: _onSelect,
                                      dropdownMenuEntries:
                                          _buildMenuList(departmentList),
                                    ),
                                  ),

效果:

SizeBox该改的是展开项的宽高

5.嵌套对话框直接关闭

showDialog本质新增了一个页面堆栈,使用Navigator进行管理

 builder: (BuildContext contextofform) contextofform中含有当前页面路由信息。关闭对话框使用

Navigator.of(contextofform).pop();

嵌套关闭:

//内层
Navigator.of(context).pop();
//外层
Navigator.of(contextofform).pop();

//  Navigator.of(context).popUntil((route) => route.isFirst); 

直接弹出路由直到第一个路由为止,一般是到登录

7.事件分级:

关注点分离(Separation of Concerns)

通过将事件分级,可以将不同类型的事件处理逻辑分离开来,使得每个模块只关注特定类型的事件。这有助于代码的清晰度和可维护性。

  • 应用程序级别的事件:处理与整个应用程序相关的事件,例如应用程序的生命周期、屏幕尺寸或方向变化等。这些事件通常影响整个应用程序的状态或行为。
  • 框架级别的事件:处理与 Flutter 框架相关的事件,例如手势识别、渲染树更新等。这些事件通常影响 Flutter 框架如何处理用户交互和界面渲染。
  • 小部件级别的事件:处理与具体小部件相关的事件,例如按钮点击、文本输入等。这些事件通常影响单个小部件的行为和状态。

学习:flutter同步页面数据方法

通过setState方法:

这是 Flutter 最简单的状态管理方式之一。通过调用 setState 方法,可以通知 Flutter 框架重新构建当前 Widget 的子树。当数据发生变化时,调用 setState 方法来更新 UI,Flutter 将会根据新的数据重新构建 Widget 树,从而实现页面数据的同步。

原因:在路由跳转前后刷新是有区别的

//正确
//外层
Navigator.of(contextofform).pop();
await getList();

//错误
await getList();
//外层
Navigator.of(contextofform).pop();

未能解决的;

 修改数据后页面同步更新失败

控制台有数据输出,且Refresh有效

  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值