【Flutter】开发之基础Widget(二)

栏目: ASP.NET · 发布时间: 6年前

内容简介:可以看到,这个返回了一个

Flutter 的核心设计思想便是一切即 Widget ,在 Flutter 的世界里,包括 viewsviewcontrollerslayouts 等在内的概念都建立在 Widget 之上,可以理解成原生的 View

lib/main.dart 是程序的主入口

//导包
import 'package:flutter/material.dart';
//程序入口
void main() => runApp(MyApp());
//相当于主页面
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue, 
      ),
      home: MyHomePage(title: 'Home Page'),
    );
  }
}
复制代码

可以看到,这个返回了一个 MaterialAppWidget ,作为程序的主界面。

父级组件

Widget 介绍
StatelessWidget 无状态widget,类似静态页面,不与用户交互
StatefulWidget 有状态widget,可以改变,可以与用户交互

基础组件

Widget 介绍
MaterialApp 一般用作APP顶层的主页入口,可配置主题,多语言,路由等
Scaffold 一般用户页面的承载Widget,包含appbar、snackbar、drawer等material design的设定。
Appbar 一般用于Scaffold的appbar ,内有标题,二级页面返回按键等,当然不止这些,tabbar等也会需要它
Text 显示文本,类似于TextView
Image 显示图片,可以加载本地资源、file、网络图片、内存图片
TextField 输入框,类似于EditText
  • Text
Text(
          //文本
          '我是Text我是Text我是Text我是Text我是Text我是Text我是Text我是Text我是Text我是Text',
          //超出屏幕 clip裁剪,fade渐隐,ellipsis省略号
          overflow: TextOverflow.ellipsis,
          //对齐方式
          textAlign: TextAlign.center,
          //文本方向
          textDirection: TextDirection.rtl,
          //样式
          style: TextStyle(
            color: Colors.lightBlue,
            fontSize: 14,
            fontStyle: FontStyle.italic,
            backgroundColor: Colors.black87,
            //none无文字装饰,lineThrough删除线,overline文字上面显示线,underline文字下面显示线
            decoration: TextDecoration.lineThrough,
            //字母间隙
            letterSpacing: 10,
          ),
        )
复制代码
【Flutter】开发之基础Widget(二)
  • Image
方法 作用
Image.assetImage(image: new AssetImage() 加载本地图片
Image.fileImage(image: new FileImage() file
Image.memoryImage(image: new MemoryImage() 加载内存byte数组
Image.networkImage(image: new NetworkImage() 加载网络图片

其中, asset 首先需要在根目录下建立 images 文件夹,然后在 pubspec.yaml 文件中添加引用才能使用

flutter:
  uses-material-design: true
  assets:
    - images/ic_launcher.png
复制代码
Image.asset(
                'images/ic_launcher.png',
                width: 100,
                height: 100,
                fit: BoxFit.fitHeight,
              ),

              Image(
                image: new NetworkImage(
                    'http://n.sinaimg.cn/sports/2_img/upload/cf0d0fdd/107/w1024h683/20181128/pKtl-hphsupx4744393.jpg'),
                width: 100,
                height: 100,
                fit: BoxFit.cover,
              )
复制代码
【Flutter】开发之基础Widget(二)
  • TextField
TextField(
            //键盘输入方式
            keyboardType: TextInputType.number,
            decoration: InputDecoration(
              //提示文字
              hintText: '请输入手机号',
              //内容边距
              contentPadding: EdgeInsets.all(10),
              //提示文字样式
              hintStyle:
                  TextStyle(color: Colors.deepOrangeAccent, fontSize: 18),
              //边框
              border: OutlineInputBorder(
                //圆角
                borderRadius: BorderRadius.all(Radius.circular(4)),
                borderSide: BorderSide(color: Colors.deepOrange),
              ),
            ),
            //文字改变时调用
            onChanged: (String content) {
              print("content=" + content);
            },
            //光标颜色
            cursorColor: Colors.deepOrangeAccent,
            //光标圆角
            cursorRadius: Radius.circular(4),
            //光标宽度
            cursorWidth: 2,
          )
复制代码

布局型

Widget 多个子Widget 介绍
Container 默认充满,包含了padding、margin、color、宽高、decoration 等配置
Padding 用于设置padding, 对,你没有猜错,绝大部分Widget是没有padding属性的
Center 用于居中显示
Column 垂直布局,类似于LinearLayout 的orientation="vertical"
Row 水平布局,类似于LinearLayout 的orientation="horizontal"
Stack 类似于relativeLayout 或者FrameLayout
ListView 类似于ListView或者RecyclerView
Container
Padding
Column
Row
class ContainerDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ContainerDemo'),
      ),
      body: Container(
        margin: EdgeInsets.all(10),
        padding: EdgeInsets.only(left: 10, right: 20),
//        color: Colors.orangeAccent,
        decoration: new BoxDecoration(
            //设置了decoration的color,就不能设置Container的color,否则会报错
            color: Colors.white,
            borderRadius: BorderRadius.all(Radius.circular(10)),
            border: new Border.all(width: 10, color: Colors.blue)),
        child: Column(
          //Column 垂直方向,Row 水平方向
          mainAxisAlignment: MainAxisAlignment.center,
          //max相当于match_parent,min相当于wrap_content
          mainAxisSize: MainAxisSize.max,
          verticalDirection: VerticalDirection.up,
          children: <Widget>[
            Container(
              padding: EdgeInsets.all(10),
              margin: EdgeInsets.all(20),
              color: Colors.black54,
              child: Text(
                '1111111',
              ),
            ),
            Text(
              '111FFFFg',
              style: TextStyle(
                fontSize: 18,
                backgroundColor: Colors.black54,
              ),
            ),
            Text('222'),
            Text('333'),
          ],
        ),
      ),
    );
  }
}
复制代码
  • Stack

Stack 类似于relativeLayout 或者FrameLayout,有2种定位方式

1. alignment 作用于是全部的子 Widget

class StackDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Stack(
        textDirection: TextDirection.ltr,
        //以整个组件的中心为坐标原点,x、y 偏移量取值范围为 [-1,1],
        // 如果 x 的偏移量大于 0,则表示向右偏移,小于 0 则向左偏移;
        // 如果 y 轴的偏移量大于 0 则向下偏移,小于 0 则向上偏移。
//        alignment: Alignment(0, 0),
        //AlignmentDirectional.topStart:垂直靠顶部水平靠左对齐
        //AlignmentDirectional.topCenter:垂直靠顶部水平居中对齐
        //AlignmentDirectional.topEnd:垂直靠顶部水平靠右对齐
        //AlignmentDirectional.centerStart:垂直居中水平靠左对齐
        //AlignmentDirectional.center:垂直和水平居中都对齐
        //AlignmentDirectional.centerEnd:垂直居中水平靠右对齐
        //AlignmentDirectional.bottomStart:垂直靠底部水平靠左对齐
        //AlignmentDirectional.bottomCenter:垂直靠底部水平居中对齐
        //AlignmentDirectional.bottomEnd:垂直靠底部水平靠右对齐
        alignment: AlignmentDirectional.centerEnd,
        children: <Widget>[
          Container(
            color: Colors.black54,
            child: Text(
              '1111111',
            ),
          ),
          Text('111FFFFg',
              style: TextStyle(fontSize: 18, backgroundColor: Colors.black54)),
          Text('22222222')
        ],
      ),
    );
  }
}
复制代码
【Flutter】开发之基础Widget(二)
2. Positioned 只能控制单个 Widget ,主要有 leftrighttopbottomwidthheight

几个属性,分别表示距左、右、上、下的边距,长度和宽度

注意:

1) leftright 并存时, left 生效; topbottom 并存时, top 生效

2) leftrightwidth 不能并存, topbottomheight 不能并存,会报错

class StackDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Stack(
        textDirection: TextDirection.ltr,
       children: <Widget>[
          Container(
            color: Colors.black54,
            child: Text(
              '1111111',
            ),
          ),
          Positioned(
            top: 100,
            child: Text(
              '111FFFFg',
              style: TextStyle(
                fontSize: 18,
                backgroundColor: Colors.black54,
              ),
            ),
          ),
          Positioned(
            child: Text('22222222'),
            right: 10,
            top: 200,
          )
        ],
      ),
    );
  }
}
复制代码
【Flutter】开发之基础Widget(二)
  • ListView

主要有3种构造方式 ListView.builder ListView.separated ListView.custom

1. ListView.builder

使用自带的 item -- ListTile

class ListViewDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ListViewDemo'),
        centerTitle: true,
      ),
      body: Container(
        color: Colors.white,
        child: ListView.builder(
          //item
          itemBuilder: (context, index) {
            return ListTile(
              //前置图标
              leading: new Icon(Icons.list),
              title: new Text('标题'),
              subtitle: new Text('副标题'),
              //后置图标
              trailing: new Icon(Icons.arrow_forward_ios),
              //内容边距
              contentPadding: EdgeInsets.all(10),
            );
          },
          //数量
          itemCount: 10,
          //内容适配
          shrinkWrap: true,
          //内边距
          padding: EdgeInsets.only(left: 10),
          //是否倒叙
          reverse: false,
          //item 高度 让item加载更加高效
          itemExtent: 50,

          //滑动方式
          //AlwaysScrollableScrollPhysics() 总是可以滑动
          //NeverScrollableScrollPhysics禁止滚动
          //BouncingScrollPhysics 内容超过一屏 上拉有回弹效果
          //ClampingScrollPhysics 包裹内容 不会有回弹
          physics: BouncingScrollPhysics(),
          //预加载
          cacheExtent: 10,
        ),
      ),
    );
  }
}
复制代码
【Flutter】开发之基础Widget(二)
2. ListView.separated

相当于原生中的多类型,核心是 separatorBuilder ,与 itemBuilder 是一同渲染的,可以用它来实现分割线

ListView.separated(
          itemBuilder: (context, index) {
            return ListTile(
              //前置图标
              leading: new Icon(Icons.list),
              title: new Text('标题'),
              subtitle: new Text('副标题'),
              //后置图标
              trailing: new Icon(Icons.arrow_forward_ios),
              //内容边距
              contentPadding: EdgeInsets.all(10),
            );
          },
          separatorBuilder: (context, index) {
            return Divider(
              color: Colors.black45,
              height: 10,
              //左边缩进
              indent: 50,
            );
          },
          itemCount: 20,
        )
复制代码
【Flutter】开发之基础Widget(二)
3. ListView.custom

前2种方式是此方式的 快捷方式 ,虽然不常用,但还是要了解下

ListView.custom(
          childrenDelegate: SliverChildBuilderDelegate((context, index) {
            return ListTile(
              //前置图标
              leading: new Icon(Icons.list),
              title: new Text('标题 custom'),
              subtitle: new Text('副标题 custom'),
              //后置图标
              trailing: new Icon(Icons.arrow_forward_ios),
              //内容边距
              contentPadding: EdgeInsets.all(10),
            );
          }),
        )
复制代码

效果同方式1

示例

模拟器上间隔线显示有问题,真机正常

【Flutter】开发之基础Widget(二)
ListViewDemo

相关代码

class ListViewDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ListViewDemo'),
        centerTitle: true,
      ),
      body: Container(
        color: Colors.white,
        child: ListView.separated(
          itemBuilder: ((context, index) {
            return MoveItem();
          }),
          separatorBuilder: (context, index) {
            return Divider(
              color: Colors.black45,
              height: 10,
            );
          },
          itemCount: 10,
        ),
      ),
    );
  }
}
复制代码

MoveItem 相关代码

class MoveItem extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.all(4),
      child: Row(
        children: <Widget>[
          ClipRRect(
            borderRadius: BorderRadius.circular(4),
            child: Image.network(
              'http://n.sinaimg.cn/sports/2_img/upload/cf0d0fdd/107/w1024h683/20181128/pKtl-hphsupx4744393.jpg',
              width: 100,
              height: 150,
              fit: BoxFit.fill,
            ),
          ),
          Padding(
            padding: EdgeInsets.only(left: 15),
          ),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              Text(
                '狄仁杰之四大天王',
                style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
              ),
              Text('豆瓣评分6.6'),
              Text('类型:动作、惊悚、冒险'),
              Text('导演:徐克'),
              Row(
                children: <Widget>[
                  Text('主演:'),
                  Padding(
                    padding: EdgeInsets.only(left: 10),
                  ),
                  Container(
                    width: 40,
                    height: 40,
                    child: CircleAvatar(
                      backgroundImage: NetworkImage(
                          'http://n.sinaimg.cn/sports/2_img/upload/cf0d0fdd/107/w1024h683/20181128/pKtl-hphsupx4744393.jpg'),
                    ),
                  ),
                  Container(
                    width: 40,
                    height: 40,
                    margin: EdgeInsets.only(left: 10),
                    child: CircleAvatar(
                      backgroundImage: NetworkImage(
                          'http://n.sinaimg.cn/sports/2_img/upload/cf0d0fdd/107/w1024h683/20181128/pKtl-hphsupx4744393.jpg'),
                    ),
                  ),
                  Container(
                    width: 40,
                    height: 40,
                    margin: EdgeInsets.only(left: 10),
                    child: CircleAvatar(
                      backgroundImage: NetworkImage(
                          'http://n.sinaimg.cn/sports/2_img/upload/cf0d0fdd/107/w1024h683/20181128/pKtl-hphsupx4744393.jpg'),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ],
      ),
    );
  }
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Purely Functional Data Structures

Purely Functional Data Structures

Chris Okasaki / Cambridge University Press / 1999-6-13 / USD 49.99

Most books on data structures assume an imperative language such as C or C++. However, data structures for these languages do not always translate well to functional languages such as Standard ML, Ha......一起来看看 《Purely Functional Data Structures》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具