FlutterFlutter博客资源

Flutter基础小组件(Widgets)

2019-03-13  本文已影响11人  wayDevelop

github地址

Flutter 的界面基本由Widgets组成,widget需要位于MaterialApp内才能正常显示。

Flutter提供了许多widgets,可帮助您构建遵循Material Design的应用程序。
Material应用程序以MaterialApp widget开始, 该widget在应用程序的根部创建了一些有用的widget,其中包括一个Navigator, 它管理由字符串标识的Widget栈(即页面路由栈)。可以让您的应用程序在页面之间的平滑的过渡。 是否使用MaterialApp完全是可选的,但是使用它是一个很好的做法。

Flutter有一套丰富、强大的基础widget,其中以下是很常用的:

const Text(  "hello flutter!",
            textAlign: TextAlign.center,
            maxLines: 1,
            overflow: TextOverflow.ellipsis, // 溢出显示。。。
            style: TextStyle(fontSize: 30.0,// 文字大小
               color: Colors.yellow),// 文字颜色
          ),
//水平布局
Widget buildColumns() {
  Row column = new Row(
    children: <Widget>[
      new Text('hello'),
      new Icon(Icons.mail),
    ],
  );
  return column;
}

//垂直布局
Widget buildColumns1() {
  Column column = new Column(
    children: <Widget>[
      new Icon(Icons.info),
      new Icon(Icons.mail),
    ],
  );
  return column;
}

Container的组成如下:Container参考文章

最里层的是child元素;
child元素首先会被padding包着;
然后添加额外的constraints限制;
最后添加margin。

Container的绘制的过程如下:

首先会绘制transform效果;
接着绘制decoration;
然后绘制child;
最后绘制foregroundDecoration。

BoxDecoration的image属性相当于设置的是背景图。但是image会绘制在color 和gradient之上。
image是需要一个DecorationImage类的实现。DecorationImage的属性和Image组件比较类似,可以复用Image组件中的ImageProvider。

如何表达尽可能大这样的意思?(类似于android中的match_parent)Flutter中可以使用double.infinity来做出类似的表达。

设置边框&padding&margin&圆角&背景图

new Container(
         alignment: Alignment.center,
         padding: const EdgeInsets.all(15.0),
         margin: const EdgeInsets.all(15.0),
         decoration: new BoxDecoration(
           border: new Border.all(
             color: Colors.red,
           ),
           image: const DecorationImage(
             image: const NetworkImage(
               'https://gw.alicdn.com/tfs/TB1CgtkJeuSBuNjy1XcXXcYjFXa-906-520.png',
             ),
             fit: BoxFit.contain,
           ),
           //borderRadius: const BorderRadius.all(const Radius.circular(6.0)),
           borderRadius: const BorderRadius.only(
             topLeft: const Radius.circular(3.0),
             topRight: const Radius.circular(6.0),
             bottomLeft: const Radius.circular(9.0),
             bottomRight: const Radius.circular(0.0),
           ),
         ),
         child: Text(''),
       ),

Scaffold是Material中主要的布局组件,现在来看看Scaffold的几个重要属性:

1、appBar appBar显示在Scaffold的顶部。

appBar: new AppBar(
        title: new Text('Scaffold Widget Demo'),
        centerTitle: true,
        backgroundColor: Colors.red,
      ),


centerTitle:让文本居中显示。默认是居左显示

backgroundColor:导航栏背景颜色

2、backgroundColor 这个是整个Scaffold的背景颜色

3、body 主要内容的视图区域,在这个里面,展示的是你的核心内容

4、bottomNavigationBar 用于显示底部导航栏

5、floatingActionButton 浮动于body右上角的按钮

6、floatingActionButtonLocation 决定floatingActionButton按钮的位置

stack

在实际开发中,还是需要在一些Widgets的上面再覆盖上新的Widgets。这时候就需要层式布局了。这种布局在Native上,以android为例,类似于relativeLayout 或者FrameLayout。在Flutter中使用的是Stack。
实际使用中Stack中的子Widgets分为两种:

positioned

是包裹在组件Positioned中的组件
可以通过Positioned属性灵活定位

non-positioned
没有包裹在Positioned组件中
需要通过父Widget Stack 的属性来控制布局

对于non-positioned children, 我们通过控制Stack的alignment属性来控制对齐方式。Positioned的布局方式类似于H5&weex中的position布局中的absolute布局方式。通过设置距离父组件上下左右的距离,Positioned对象能在Stack布局中更加灵活的控制view的展现方式。

层叠布局

new Container(
            color: Colors.yellow,
            height: 150.0,
            width: 500.0,
            child: new Stack(children: <Widget>[
              new Container(
                color: Colors.blueAccent,
                height: 50.0,
                width: 100.0,
                alignment: Alignment.center,
                child: Text('unPositioned'),
              ),
              new Positioned(
                  left: 40.0,
                  top: 80.0,
                  child: new Container(
                    color: Colors.pink,
                    height: 50.0,
                    width: 95.0,
                    alignment: Alignment.center,
                    child: Text('Positioned'),
                  )),
            ]))

Visibility

当你看完Flutter Widge文档的时候,我们突然发现一个略显尴尬的问题:组件是否显示怎么控制?貌似所有的组件中都没有这个属性!这不坑了,咋办?
目前看方法无非如下几个:

单个组件‘隐藏’自己。在build方法中返回一个空的Container.

@override
Widget build(BuildContext context) {
  return isVisible
      ? Widget //真的Widget
      : new Container(); //空Widget 仅仅占位 并不显示
}

多个child

在父容器的children字段的list中,删除掉对应的cell。

sample code如下:
@override
Widget build(BuildContext context) {
  return new Offstage(
          offstage: !isVisible,
          child:child);
}
@override
Widget build(BuildContext context) {
  return new AnimatedOpacity(
        duration: Duration(milliseconds: 10),
        opacity: isVisible ? 1.0 : 0.0,
          child:child);
}

visibility的控制还是比较麻烦的。这是Flutter设计上不符合正常习惯的一个点,需要大家重点关注。

参考链接


上一篇 下一篇

猜你喜欢

热点阅读