flutter项目中使用

一些小部件

  1. GestureDetector: 手势

手势表示由一个或多个指针移动组成的动作。主要有以下几种
onTap :点击事件触发

  1. Divider() 设置分割线
  2. SharedPreferences数据存储
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.getKeys()//取出所有key
  1. MainAxisAlignment 水平排列

报错:A RenderFlex overflowed by 8.0 pixels on the bottom
使用SingleChildScrollView处理使之滑动

  1. Expanded:填满剩余空间

Spacer : Row、Column、Flex的子控件的空隙

RefreshIndicator : 下拉刷新

  1. Scaffold

实现了Material风格的基本布局结构,它提供了展示drawers、snack bars和bottom sheets的功能。

  1. EdgeInsets:
 //分别指定四个方向的填充。
 fromLTRB(double left, double top, double right, double bottom),
 //所有方向均使用相同数值的填充。
 all(doube value),
 //可以设置具体某个方向的填充(可以同时指定多个方向)。
 only(top:0,right:0,bottom:0,left:0),
 //用于设置对称方向的填充,vertical指top和bottom,horizontal指left和right。
 symmeric(vertical:0,horizontal:0),
  1. Padding:

Object -> Diagnosticable -> DiagnosticableTree -> Widget -> RenderObjectWidget -> SingleChildRenderObjectWidget -> Padding

MaterialApp(
debugShowCheckedModeBanner: false,//去掉右上角DEBUG标签
)
  1. 定义一个button
new RaisedButton(
   onPressed:(){
     Navigator.pushNamed(context, "/screen2")
   },
   child: new Text("Push to Screen 2"),
),
  1. PreferredSize : 取消默认,使用自定义appbar
AppBar(
        backgroundColor: ConstValue().barSearchBG, //定义背景颜色
        automaticallyImplyLeading: false, //是否显示默认的后退按钮
        elevation: 0, //阴影,值越大越清楚
        titleSpacing: 0,
        title: ....
        ,
      )
  1. Container : 基础控件,可以组成任意想要的效果

Object > Diagnosticable > DiagnosticableTree > Widget > StatelessWidget > Container

decoration属性介绍:
border:增加一个边框,
hintText:未输入文字时,输入框中的提示文字,
prefixIcon:输入框内侧左面的控件,
labelText:一个提示文字。输入框获取焦点/输入框有内容 会移动到左上角,否则在输入框内,labelTex的位置.
suffixIcon: 输入框内侧右面的图标.
icon : 输入框左侧添加个图标


Container(
          //边框设置
         decoration: new BoxDecoration(
         //背景
        color: ConstValue().buttonBG,//Colors.lightBlue[50],
        //设置四周圆角 角度
        borderRadius: BorderRadius.all(Radius.circular(2.0)),
         //设置四周边框
         border: new Border.all(width: 1, color: ConstValue().buttonBG,),
        ),

        child: ....
)
  1. 获取不到context

当获取不到context上下文时,可以通过这种方式跳转页面

GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
	....
  navigatorKey.currentState.pushAndRemoveUntil(
              new MaterialPageRoute(
                  builder: (BuildContext context) => LoginScreen()), (
                  route) => route == null);
  1. Providers

更新状态
定义对象

class TaskModel with ChangeNotifier {
	...
    void update() async {
    ...
    notifyListeners();
    }
 }

初始化

final providers = Providers()
    ..provide(Provider<TaskModel>.value(TaskModel()))

取值或者调用方法赋值

Provide.value<TaskModel>(context).update()

在widget使用(notifyListeners会通知到这里进行更新)

Provide<SearchModel>(
              builder: (context, child, search) {
                if(search.info !=  null){
                  print(search);
                  loadData();
                }
                return Container();
     }
)

dart相关

  1. async await
void update() async{
	await print("异步");
}

http.get() ->import ‘package:http/http.dart’ as http;

dynamic x = ‘hello’;//dynamic编译时不会判断数据类型,但是运行时会推断,dart的语法检查失效

  1. ??双问号运算符表示"如果为空"。

例如,采用以下表达式。
String a = b ?? ‘hello’;

  1. 字符串数组

List strlist

  1. json转换请求结果

jsonDecode ->import ‘dart:convert’;

jsonDecode(utf8.convert(response.bodyBytes))
  1. 对象的使用
class Search {
  Search({ //定义构造方法
  this.startDate, 
  this.endDate,
  this.orderCode,
  });

  String  startDate, endDate,orderCode;

//使用对象比较,重写了相等和hashCode
    @override 
    bool operator ==(Object other) =>
    identical(this, other) || other is Search &&runtimeType == other.runtimeType &&
    startDate == other.startDate &&
    orderCode == other.orderCode &&
    endDate == other.endDate;
        
    @override
    int get hashCode => orderCode.hashCode ^ endDate.hashCode ^ startDate.hashCode;

   factory Search.fromJson(Search other) {
      return Search(
        startDate: other.startDate,
        endDate: other.endDate,
        orderCode: other.orderCode,
      );
    
  }
  //相等于toString
    void call(){
      print("startDate is $startDate , endDate is $endDate , orderCode is $orderCode");
    }
}
  1. 时间区间
var startDate = new DateTime.now();
...
var se = new DateTime.now().difference(startDate).inMilliseconds;

webview相关

webview_flutter支持H5的input(file)标签上传文件

该组件内使用input file,然而flutter webview_flutter貌似还不支持input选择相册打开相机
参照了其它人的文章,特地在这里记录下.
https://blog.csdn.net/kameleon2013/article/details/109104531
https://blog.csdn.net/chjqxxxx/article/details/52724983
下载最新 webview_flutter插件版本,加入相册选择,相机拍照,本地编译之后,完美解决

webview https无法打开http的图片链接
#在FlutterWebView构造方法内,设置混用
import android.webkit.WebSettings; //引用的包名
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0以上强制启用https和http混用模式
      webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    }

安卓release混淆问题

高德导航打开时闪退

异常信息: no non-static method "Lcom/autonavi/base/ae/gmap/GLMapEngine; …
最后是把代码混淆关了,暂时解决这一下问题

flutter安卓插件引用FastJson

release打包后,无法使用泛型
https://blog.csdn.net/zgzczzw/article/details/72330190

其它

flutter_downloader
Unhandled Exception: Null check operator used on a null value
E/flutter (20856): #0      FlutterDownloader.registerCallback (package:flutter_downloader/src/downloader.dart:389:71)

参考官网新版本demo
https://pub.flutter-io.cn/packages/flutter_downloader/example

创建flutter插件
# 创建一个名为pda_print的plugin
flutter create --org cn.meyoung.plugins --template=plugin \
--platforms=android,ios -a java pda_print
apk下载之后.不能自动打开安装(被识别为zip格式)
把在nginx配置文件中指定apk格式为application/vnd.android.package-archive

Android文件Apk下载变ZIP压缩包解决方案

flutter安卓代码引用第三方库与其它flutter插件使用的库冲突

报错: com.google.zxing:core:3.3.3 CheckDuplicatesRunnable
通过gradlew 找到重复包并删除,最后创建flutter插件把安卓代码移到插件中

flutter build apk 分别编译出32位,64位文件
$ flutter build apk --target-platform  android-arm,android-arm64 --split-per-abi
flutter Icon的使用

图标与名字
flutter 图标库

安卓定位权限

前台运行权限 : ACCESS_FILE_LOCATION和ACCESS_COARSE_LOCATION
后台运行权限: ACCESS_BACKGROUND_LOCATION权

最后,一些说明

const MaterialButton({
  Key key,
  @required VoidCallback onPressed,              //点击按钮的回调函数
  ValueChanged<bool> onHighlightChanged,         //高亮变化的回调
  ButtonTextTheme textTheme,                     //按钮的字体主题
  Color textColor,                               //字体颜色
  Color disabledTextColor,                      //禁用时的字体颜色
  Color color,                                  //按钮背景色
  Color disabledColor,                          //禁用时的背景色
  Color focusColor,                              //联动节点获得焦点时的颜色
  Color hoverColor,                              //鼠标悬停时的颜色
  Color highlightColor,                          //按下背景颜色(长按,不是点击)
  Color splashColor,                            //水波纹颜色
  Brightness colorBrightness,                   //按钮亮度
  double elevation,                              //阴影尺寸
  double focusElevation,                        //联动节点获得焦点时的阴影尺寸
  double hoverElevation,                        //鼠标悬停时阴影尺寸
  double highlightElevation,                    //长按阴影尺寸
  double disabledElevation,                    //禁用时的阴影尺寸
  EdgeInsetsGeometry padding,                  //内边距
  ShapeBorder shape,                            //按钮的形状
  Clip clipBehavior: Clip.none,                //裁剪
  FocusNode focusNode,                         //联动节点
  MaterialTapTargetSize materialTapTargetSize,  //有效的点击区域大小
  Duration animationDuration,                  //动画时间  
  double minWidth,                              //最小宽
  double hight,                                //高度
  Widget child                                  //子节点
})

输入框

TextField(
           autofocus: false,
           controller: controller,
           //绑定焦点1
           focusNode: focusNode2,
           keyboardType: TextInputType.text,
            onChanged: (remark) {getForm('remark',remark);},
           style: TextStyle(fontSize: 12,//输入文字颜色和大小
           		color:Color.fromRGBO(35, 35, 35, 1),
           		decoration: TextDecoration.none, //去下划线
           	),
           decoration: InputDecoration(
           icon: Icon(Icons.assignment_ind),
           hintText: '请输入备注信息',//文字提示
           hintStyle: TextStyle(color:Color.fromRGBO(187, 187, 187, 1)),//提示文字颜色
           border: InputBorder.none,//去掉下划线
           ),
 )
//构造
  const TextField({
    Key key,
    this.controller,            //控制器,控制TextField文字
    this.focusNode,       //焦点
    this.decoration: const InputDecoration(),      //输入器装饰
    TextInputType keyboardType: TextInputType.text, //输入的类型
    this.style,
    this.textAlign: TextAlign.start,
    this.autofocus: false, //是否自动"对焦"
    this.obscureText: false,  //是否隐藏输入
    this.autocorrect: true,
    this.maxLines: 1,
    this.maxLength,
    this.maxLengthEnforced: true,
    this.onChanged,            //文字改变触发
    this.onSubmitted,          //文字提交触发(键盘按键)
    this.onEditingComplete,  //当用户提交可编辑内容时调用
    this.inputFormatters,
    this.enabled,
    this.cursorWidth = 2.0,
    this.cursorRadius,
    this.cursorColor,
    this.keyboardAppearance,
  })
AppBar(
       backgroundColor: Colors.transparent, //设为透明
        elevation: 0, //阴影深度
        toolbarHeight:0 //把高度去掉
        )
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值