flutter 一些技巧

flutter 一些技巧

[toc]

局部设置明暗主题

image-20200408163613591

多设备启动

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
  // 使用 IntelliSense 了解相关属性。
  // 悬停以查看现有属性的描述。
  // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Current Device",						// 设备名
      "request": "launch",								// 操作
      "type": "dart",											// 语言类型
       "program": "lib/main_dev.dart" // 入口
    },
    {
      "name": "Android",
      "request": "launch",
      "type": "dart",
      "deviceId": "android",
        "program": "lib/main_dev.dart" // 入口
    },
    {
      "name": "iPhone",
      "request": "launch",
      "type": "dart",
      "deviceId": "iPhone"
    }
  ],
  "compounds": [
    {
      "name": "All Devices",
      "configurations": ["Android", "iPhone"]
    }
  ]
}

image-20200415104534779

ListView 嵌套 ListView

1
2
 			  shrinkWrap: true, 								//解决无限高度问题
		      physics: new NeverScrollableScrollPhysics(),		//禁用滑动事件

刷新效果 , 即转圈动画

image-20200513102433388

背景透明的路由

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Navigator.of(context).push(
  PageRouteBuilder(
    opaque:false,
    pageBuilder: (context, animation, secondaryAnimation) {
      return Scaffold(
        backgroundColor: Colors.transparent,
        body: SafeArea(
          child: Stack(
            children: <Widget>[
             //...
            ],
          ),
      )
    );
    }
));

屏幕适配

参考 https://github.com/jiang111/flutter_code/blob/master/lib/ui_4/home_page.dart

全局坐标转换局部坐标

1
2
RenderBox box = context.findRenderObject();
_tapPos = box.globalToLocal(details.globalPosition);

强制竖屏

1
2
3
 // 强制竖屏
  // SystemChrome.setPreferredOrientations(
  //     [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);

网络请求处理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   return Center(
        child: FutureBuilder<dynamic>(
      future: CommentApi.getCommentList(
          elem["id"], 10, 0), // a previously-obtained Future<String> or null
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        switch (snapshot.connectionState) {
          // 未执行

          case ConnectionState.none:
            // 连接到异步操作
            return Text('Press button to start.');
          case ConnectionState.active:
          // 请求中
          case ConnectionState.waiting:
            //  // 请求未结束,显示loading
            return Text(""); 
            // return CircularProgressIndicator();
          case ConnectionState.done:
            // 请求完成
            if (snapshot.hasError) return Text('Error: ${snapshot.error}');

            List list = snapshot.data as List;
            return Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: comment(context, list),
            );
        }
        return null; // unreachable
      },
    ));  

时间格式化

1
2
3
4
5
import 'package:intl/intl.dart'   


var _formatter = new DateFormat('yyyy-MM-dd');
    var _createTime = _formatter.format(DateTime.parse(elem["create_time"]));

渐变色

1
2
3
4
5
6
7
8
Container(
      decoration: BoxDecoration(
          gradient: LinearGradient(
        colors: [Color(0xFFfbab66), Color(0xFFf7418c)],
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
      )),
    );

圆形头像

1
2
3
4
  CircleAvatar(
                  maxRadius: 15,
                  backgroundImage: NetworkImage(_icon),
 ),

likebutton

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
LikeButton(
  onTap: (bool flag) {
    return onLikeButtonTap(flag, _id);
  },
  isLiked: _likes,
  size: 18,
  likeCount: _count,
  countPostion: CountPostion.left,
  likeCountPadding: EdgeInsets.only(right: 5),
  likeBuilder: (bool flag) {
    return Image(
      image: AssetImage("images/like.png"),
      height: 18,
      color: flag
      ? Colors.redAccent
      : Colors.grey[600],
    );
  },
),



 Future<bool> onLikeButtonTap(bool isLiked, String id) {
    if (isLiked != true) {
      // send your request here
      CommentApi.putLike(id).then((value) {
        if (value.statusCode != 200) {
          message("网络异常,请稍后再试");
          isLiked = isLiked;
        } else {
          isLiked = true;
        }
      });
    }

 
    final Completer<bool> completer = new Completer<bool>();
    Timer(const Duration(milliseconds: 200), () {
      // if your request is failed,return null,
      completer.complete(isLiked);
    });
    return completer.future;
  }

图片上传

https://www.jianshu.com/p/b582daddd737

http://47.105.149.100/web/flutter-cai-kang-ri-ji-chi-xu-geng-xin-

点击可修改的属性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  Container(
    height: 25,
    width: 100,
    alignment: Alignment.centerLeft,
    child: TextField(
      onTap: () {
        if (authorController.text ==
            UserApi.model.getUserInfo["nick_name"]) {
          authorController.text = '';
        } // 默认值则自动置空
      },
      maxLines: 1,
      maxLength: 7, // 限制最长字符
      controller: authorController,
      decoration: InputDecoration(
        counterText: "", // 不显示字符串数量
        disabledBorder: InputBorder.none,// 无边框
        enabledBorder: InputBorder.none,
        focusedBorder: InputBorder.none,
        border: InputBorder.none,
        // contentPadding: EdgeInsets.all(10.0),
      ),
      autofocus: false, 
      textAlign: TextAlign.left,
      style: Theme.of(context).textTheme.bodyText2,
    )),
],
),

组件位置

1
2
3
4
5
GlobalKey anchorKey = GlobalKey();

RenderBox renderBox =
  anchorKey.currentContext.findRenderObject();
var offset = renderBox.localToGlobal(Offset(0.0, 0.0));

image-20200616091106898

延迟执行

1
2
3
4
5
// 延时1s执行返回
Future.delayed(Duration(seconds: 1), (){
    Navigator.of(context).pop();
    print('延时1s执行');
});

wifi 真机调试

https://juejin.im/post/5c9848cae51d450d91120278

image-20200629133946887

定时器 循环执行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import 'dart:async';  // 引入定时去所需要的包
Timer _timer;  // 定义一个变量,在页面销毁时需要用到,如果在定时器内部已经销毁了,可以不需要
int _count = 0;  // 一切为了演示。定义的变量
...
myTimer() {  // 定义一个函数,将定时器包裹起来
  _timer = Timer.periodic(Duration(milliseconds: 1000), (t) {
    _count++;
    if (_count==5) {
      t.cancel();  // 定时器内部触发销毁
    }
  });
}
...
@override
void dispose(() {
  if (_timer != null) {   // 页面销毁时触发定时器销毁
    if (_timer.isActive) {  // 判断定时器是否是激活状态
      _timer.cancel();
    }
  }
  super.dispose();
});

https://juejin.im/post/5cada409e51d456e5b66ad1b

https://juejin.im/post/5d81cf6d518825485e227b8c

仅仅执行一次, 在构造中写逻辑

1
2
3
4
5
  MineView() {
    WidgetsBinding.instance.addPostFrameCallback((callback) {
      HttpUtils.userModel.controller.callRefresh();
    });
  }

自定义高度 appbar

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
      appBar: AppBar(
        brightness: Brightness.dark,
        leading: navigatPop(context, color: Colors.white),
        backgroundColor: Colors.blue[300],
        bottom: PreferredSize(
            child: Column(
              children: [
                Container(
                  padding: EdgeInsets.only(left: 20, bottom: 30),
                  alignment: Alignment.centerLeft,
                  child: Text(
                    title,
                    style: Theme.of(context)
                        .textTheme
                        .headline6
                        .copyWith(color: Colors.white),
                  ),
                ),
              ],
            ),
            preferredSize: Size(double.infinity, 70)),
      ),

滑动删除

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  Slidable(
        key: Key(index.toString()),
        actionPane: SlidableScrollActionPane(), //滑出选项的面板 动画
        actionExtentRatio: 0.25,
        dismissal: SlidableDismissal(
          child: SlidableDrawerDismissal(),
          onWillDismiss: (actionType) {
            return action(index, e.id);
          },
          onDismissed: (actionType) {
            print(actionType);
          },
        ),
      secondaryActions: <Widget>[
        Padding(
            padding: EdgeInsetsDirectional.only(top: 20, bottom: 15),
            child: IconSlideAction(
                caption: 'Delete',
                color: Colors.red,
                icon: Icons.delete,
                closeOnTap: false,
                onTap: () {
                  showIosDialog(context, title: title, desc: desc)
                      .then((value) {
                    if (value) {
                      action(index, e.id);
                    }
                  });
                })),
      ],

Flutter TextField设置只读不可编辑

1
2
3
4
TextField(
  enableInteractiveSelection: false,
  onTap: () { FocusScope.of(context).requestFocus(new FocusNode()); },
)

参考 : [http://www.appblog.cn/2019/01/22/Flutter%20TextField%E8%AE%BE%E7%BD%AE%E5%8F%AA%E8%AF%BB%E4%B8%8D%E5%8F%AF%E7%BC%96%E8%BE%91/](http://www.appblog.cn/2019/01/22/Flutter TextField设置只读不可编辑/)

可选的 text selectabletext

Licensed under CC BY-NC-SA 4.0
本文阅读量 次, 总访问量 ,总访客数
Built with Hugo .   Theme Stack designed by Jimmy