前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >flutter开发技巧汇总[持续更新]

flutter开发技巧汇总[持续更新]

原创
作者头像
brzhang
修改2018-12-02 15:53:30
1.7K0
修改2018-12-02 15:53:30
举报
文章被收录于专栏:玩转全栈玩转全栈

1、你应该会碰到initState会被多次执行的问题,通常发生在tabView的切换时,此时你可能要了解一下这个接口了。

代码语言:txt
复制
/// A mixin with convenience methods for clients of [AutomaticKeepAlive].
///
/// Subclasses must implement [wantKeepAlive], and their [build] methods must
/// call `super.build` (which will always return null).
///
/// Then, whenever [wantKeepAlive]'s value changes (or might change), the
/// subclass should call [updateKeepAlive].
///
/// See also:
///
///  * [AutomaticKeepAlive], which listens to messages from this mixin.
///  * [KeepAliveNotification], the notifications sent by this mixin.
@optionalTypeArgs
abstract class AutomaticKeepAliveClientMixin<T extends StatefulWidget> extends State<T> {
  // This class is intended to be used as a mixin, and should not be
  // extended directly.
  factory AutomaticKeepAliveClientMixin._() => null;

  KeepAliveHandle _keepAliveHandle;

  void _ensureKeepAlive() {
    assert(_keepAliveHandle == null);
    _keepAliveHandle = new KeepAliveHandle();
    new KeepAliveNotification(_keepAliveHandle).dispatch(context);
  }

  void _releaseKeepAlive() {
    _keepAliveHandle.release();
    _keepAliveHandle = null;
  }

或者,你不想这么麻烦,那么,你可以可以直接使用CupertinoTabScaffold这个构造你的tab框架,这个笔者验证过,切换的时候,不会导致每次都initState,

2、listview 加divider的问题

这个实际上是一个小技巧,就是将你的额row使用Container包裹一下,给他在加一个decoration即可实现了。

代码语言:txt
复制
return Container(
      decoration: BoxDecoration(
          border: Border(bottom: BorderSide(color: Colors.grey, width: 7.0))),
          ....

但实际上,还有一个更加直接的:

代码语言:javascript
复制
Divider(
  height: 1.0,
  color: colorDivider,
)

他们的区别就是上面那个对Container容器做了一个Border,因此,会充满整个屏幕,不受到padding的印象,假如你的cell设置了padding,恰好需要使用一个充满整个屏幕的divider,那么就使用这种,如果不需要,更加方便的是Divider

3、统一app的字体。

你可以在写布局的时候一开始喜欢这么写

代码语言:txt
复制
child: Text(
                    '交易 ${transList[index].transSuccNum} | 好评 ${transList[index].comment}% | 信任 ${transList[index].relay}',
                    style: TextStyle(
                        fontSize: fontSize, color: Colors.grey.shade500),
                  )

但是,我告诉你,这是一张非常不好的写法,正确的姿势应该是这样的。

代码语言:txt
复制
child: new Text(
                              '¥37,483,434',
                              style: Theme.of(context)
                                  .textTheme
                                  .subhead
                                  .copyWith(color: Colors.white),

你可能已经明白了,这种方式的好处,基于主题来统一app类字体大小,这样不至于使得你的app花里胡哨的,风格看起来不统一,请注意copyWith可以帮你改变某些属性,比如仅仅是字体颜色不符合你的要求,你可以针对性的进行更改。

4、你也许想实现一个顶部弹框,但是似乎flutter只提供了showModalBottomSheet这种,或者中间的弹框,而且占据的控件不会铺满整个width,所以

一个这样的弹框应该如何实现呢?

我这里的实现方式是参考了digloag的弹出方式,

代码语言:javascript
复制
Navigator.of(context, rootNavigator: true).push(new _DialogRoute(
  child: Selector(),
  theme: Theme.of(context, shadowThemeOnly: true),
  barrierDismissible: true,
  barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
));

这个Selector就是你实现的一个页面,背景可以设计为透明即可,_DialogRoute直接就是copy系统实现,copy过来还可以做定制。

5、SegmentedControl是苹果上的一个空间,flutter也有,只不过在使用的时候,需要import 'package:flutter/cupertino.dart';,用上后可以出去

可以你可能会遇到SegmentedControl中文字不居中的问题,请注意,最好不要直接传一个text进去,最好用container包裹一下,类似这样,那么就居中了,注意SegmentedControl已经改名为CupertinoSegmentedControl了,使用时注意一下。

代码语言:javascript
复制
children: {
  0: Container(
    child: Text(
      '聊天',
      textAlign: TextAlign.center,
      style: TextStyle(
          fontSize: 14.0,
          color: currentValue == 0 ? Colors.white : color6853AA),
    ),
    alignment: Alignment.center,
  ),
  1: Container(
    child: Text(
      '联系人',
      textAlign: TextAlign.center,
      style: TextStyle(
          fontSize: 14.0,
          color: currentValue == 1 ? Colors.white : color6853AA),
    ),
    alignment: Alignment.center,
  ),
},

6、Raisebutton需要限制大小的话,可以使用SizeBox包一下。

代码语言:javascript
复制
SizedBox(
  width: 80.0,
  height: 24.0,
  child: RaisedButton(
    elevation: 0.1,
    highlightColor: c_007AFF.withOpacity(0.5),
    color: Colors.white,
    shape: RoundedRectangleBorder(
      side: BorderSide(color: c_007AFF),
      borderRadius: BorderRadius.circular(12.0),
    ),
    onPressed: () {},
    child: Text(
      "复制URL",
      style: TextStyle(fontSize: 12.0, color: c_007AFF),
    ),
  ),
),

7、CupertinoTabScaffold包裹CupertinoTabBar实现底部切换栏,虽然说可以接解决切换tab时,反复initState的问题,但是Navigator.of(context).push...的时候,你会发现,退出的页面中包含着底部tab,怎么让底部tab不显示呢?解决的方式是:加上rootNavigator=true这个参数。

代码语言:javascript
复制
Navigator.of(context, rootNavigator: true)
    .push(CupertinoPageRoute(builder: (context) {
  return PostFeed(feedListBloc:_feedListBloc);
}));

8、很多时候我们需要多页面共享数据,以及数据模型与界面逻辑分离,以便更好的组织代码,做出更加好维护,规模更大的app,笔者从官方举办的那个“枯燥无味的flutter show”节目中发现了一种比较好的设计模式,BLOC模式,很好的实现了代码中模型与数据的分离,模型复用的问题。如果你遇到了代码复用或者说页面规模太大需要用很好的模式来分离逻辑的问题,不妨了解一下我的另外一篇文章flutter中使用bloc

9、有时候我们需要一个背景为图片,而且边缘是有弧度的背景,那么,有没有什么很好的办法来做到。

有,我这里推荐一种方式:

代码语言:javascript
复制
Container(
  width: 88.0,
  height: 120.0,
  decoration: BoxDecoration(
      image: DecorationImage(
        image: NetworkImage(
            "http://g.hiphotos.baidu.com/image/pic/item/8cb1cb13495409236b3188459f58d109b3de49b5.jpg"),
        fit: BoxFit.cover,
      ),
      shape: BoxShape.rectangle,
      borderRadius: BorderRadius.all(
        Radius.circular(5.0),
      )),
  child: SizedBox(),
)

这里是利用了可以给Container设置decoration为DecorationImage,随后给他添加一个shape的方式,在Android和ios上的效果都ok。

10、todo

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档