flutter开发中一些技巧和坑点

获取设备宽高

double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;

Android设置状态栏透明

  1. 原生修改
public class MainActivity extends FlutterActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
         // api大于21设置状态栏透明
        getWindow().setStatusBarColor(0);
    }
    GeneratedPluginRegistrant.registerWith(this);
  }
}
  1. flutter修改(么有测试过,自己测试下反正不难)
// 输出渲染
void main() {
  runApp(App());
  if (Platform.isAndroid) {
    // 以下两行 设置android状态栏为透明的沉浸。写在组件渲染之后,是为了在渲染后进行set赋值,覆盖状态栏,写在渲染之前MaterialApp组件会覆盖掉这个值。
    SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(statusBarColor: Colors.transparent);
    SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
  }
}

区别final与const

在Dart中,当你不需要去改变一个变量的时候,应该使用final或者const,而不是使用var去声明一个变量。一个final变量只允许被赋值一次,必须在定义时或者构造函数参数表中将其初始化。
const所修饰的是编译时常量,我们在编译时就已经知道了它的值,它的值是不可改变的。
const比final更加严格,看以下例子:

final List<String> list = [];
list.add('1'); // 正确

const List<String> list = [];
list.add('1'); // 错误,运行时报错:Cannot add to an unmodifiable list

final timestamp = new DateTime.now().millisecondsSinceEpoch; // 正确

const timestamp = new DateTime.now().millisecondsSinceEpoch; // 错误,编译前报错:Const variables must be initialized with a constant value

FocusScope转移焦点,隐藏输入法

166723349530a968.gif
Container(
        height: 500.0,
        child: new GestureDetector(
          onTap: () {
            // 通过GestureDetector捕获点击事件,再通过FocusScope将焦点转移至空焦点      new FocusNode()
            FocusScope.of(context).requestFocus(FocusNode());
          },
          child: Container(
              margin: EdgeInsets.all(30.0),
              child: ListView(children: <Widget>[
                TextField(
                  decoration: InputDecoration(labelText: 'Username'),
                ),
                TextField(
                  decoration: InputDecoration(labelText: 'Password'),
                )
              ])),
        ),
      ),
  • 这里传递给FocusScope的context不能在MaterialApp下面,即你需要将这部分代码放到独立的一个Widget里面

定时任务

  1. 在我们的开发之中难免要用到定时,比如我们常用的获取验证码的需求,下面请看利用定时器来实现这一功能需求
  • 定义3个变量
int _seconds = 0;
String _verifyStr  = "获取验证码";
/// 定时器Timer
Timer _timer;
  • 实现timer,代码很清晰,简单的说我设了10秒的倒计时,利用Timer.periodic方法来执行,间隔时间是1秒
/// 倒计时
  _startTimer() {
    _seconds = 10;

    _timer = Timer.periodic(new Duration(seconds: 1), (timer){
      if(_seconds == 0){
        _cancleTimer();
        return;
      }
      _seconds--;
      _verifyStr = "${_seconds}s";
      if (_seconds == 0){
        _verifyStr = "重新发送";
      }
      setState(() {});
    });
  }

  _cancleTimer(){
    _timer?.cancel();
  }

@override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
   /// 页面销毁的时候,清除timer
    _cancleTimer();
  }
  • 执行,并不是每次按都执行_startTimer,加上判断条件只有_seconds == 0时才执行效果如下图
new Container(
          padding: const EdgeInsets.only(top: 15.0, left: 15.0),
          child: new RaisedButton(
            /// 触发定时任务
            onPressed: (_seconds == 0)?(){
              _startTimer();
            }:null,
            child: new Text(_verifyStr),
            shape: new RoundedRectangleBorder(
              borderRadius: new BorderRadius.all(new Radius.circular(15.0)),
            ),
            textColor: Colors.blue,
            color: Colors.yellowAccent,
            disabledColor: Colors.yellowAccent,
            disabledTextColor: Colors.blue,
          ),
        ),
GIF.gif

利用 Container的BoxDecoration装饰实现渐变

  • 例子如下
 Container(
        decoration: BoxDecoration(gradient: LinearGradient(
          colors: [const Color(0xFFFFFFEE), const Color(0xFF999999),const Color(0xFF862547),],
          tileMode: TileMode.repeated, // repeats the gradient over the canvas
        ),),
  • 效果如下


    渐变.png
  • BoxDecoration的属性

const BoxDecoration({
    this.color, // 盒子颜色
    this.image, // 图片
    this.border, 边框颜色和线宽度
    this.borderRadius, // 圆角度
    this.boxShadow, // 阴影
    this.gradient, // 渐变
    this.backgroundBlendMode, // 混合Mode
    this.shape = BoxShape.rectangle,  // 形状
  }) 
  • 边框圆角实现
decoration: new BoxDecoration(
  border: new Border.all(color: Color(0xFFFF0000), width: 1.0), // 边色与边宽度
  color: Color(0xFF999999), //  盒子颜色
  //        borderRadius: new BorderRadius.circular((15.0)), // 圆角度
  borderRadius: new BorderRadius.vertical(top: Radius.elliptical(20, 50)), // 也可控件一边圆角大小
),
  • Dart知识点(?. / ??)
  1. ?. 运算符在左边为null的情况下会阻断右边的调用。
  2. ?? 运算符表示在左侧表达式为null时为其设置默认值。

对于表达式:

tar[a]?.tars(b)

如果tar为null或tar[a]为null或tars(b)的值为null,都会导致表达式为null。

  1. operator重载操作符
    operator 是 Dart 的一个关键字,它和运算符(如=,+,-)一起使用,表示一个 运算符重载函数,在理解时可将operator和运算符(如operator=)视为一个函数名

关于混编中退出flutter页面的时候黑屏的情况

if(Navigator.canPop(context)){
  Navigator.pop(context, true);
}else {
  SystemNavigator.pop();
}

关于ListView中嵌套使用ListView,请在子组件中设置以下属性

shrinkWrap: true,

底部弹窗默认点击消失,如何保持面板点击不消失

  • 可以子组件外面包一层GestureDetector并设置onTap为false,拦截点击事件可以使点击底部面板区域时不消失。
 showModalBottomSheet(
        context: context,
        builder: (context) {
          return GestureDetector(
            onTap: () => false,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                titleWidget,
                twoWidget,
                Expanded(
                  child: BottomUserRankingPage(
                    context,
                    lists: lists,
                  ),
                ),
              ],
            ),
          );
        });

实现跳转到广告按back返回是主界面

 Navigator.of(context).pushReplacementNamed('/Main');
 Navigator.of(context).push(WebPage);

如何强制竖屏

void main() {
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
    .then((_) {
      runApp(new MyApp());
    });
}

在线上的app,如果flutter报错,那一片红可是非常的辣眼睛,给用户的体验也很不好,其实我们可以自定义错误页面

ErrorWidget.builder = (FlutterErrorDetails details) {
    print(details.toString());
    return Center(
      child: Text("Sorry 我下班了"),
    );
  };

在Flutter中,加载本地图片会存在一个加载过程。比如点击图标做图标的切换时,那么首次会发生闪动的情况。尤其是做类似引导页这类需求是,通过左右滑动切换图片时会发生比较明显的白屏一闪而过。

解决方法很简单,就是使用 precacheImage,它将图像预存到图像缓存中。如果图像稍后被使用,它会被加载得更快。

precacheImage(AssetImage("assets/mylogo"), context);

在iOS 13中遇到了http网页打不开的问题,添加以下文字到Info.plist
yourdomain.com 是你请求的链接的域名

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>yourdomain.com</key>
            <dict>
                <key>NSExceptionAllowInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
        <key>NSAllowsArbitraryLoadsInWebContent</key>
        <true/>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353