Flutter 布局Layout,富文本与状态管理State

Flutter 布局Layout,富文本与状态管理State

1. 普通文本

Flutter中普通文本使用Text()函数创建,常见的属性如下:

  • textAlign: 文本位置
    • enum TextAlign {
      left,
      right,
      center,
      justify,///拉伸以软换行符结尾的文本行,以填充其宽度容器。以硬换行符结尾的行朝[start]边缘对齐。
      start, ///在容器的前端对齐文本。对于从左到右的文本,这是左边缘。对于从右到左的文本,这是右边缘。
      end, //在容器的尾端对齐文本。对于从左到右的文本,这是右边缘。对于从右到左的文本,这是左边缘。
      }
  • maxLines: 文本展示行数
  • style: 文字样式
    • TextStyle({
      this.inherit = true, //继承
      this.color,//文字颜色
      this.backgroundColor, //背景色
      this.fontSize, //字体大小
      this.fontWeight,//加粗效果
      this.fontStyle, //正常-斜体
      this.wordSpacing, //文字间距
      this.background, //背景(可以是图片)
      this.shadows, //阴影
      }
  • overflow: 换行模式:(常用的是展示不全展示省略号)
    • enum TextOverflow {
      clip, ///剪辑溢出的文本以修复其容器
      fade, ///渐变效果
      ellipsis,///省略号…
      visible,///在其容器外渲染溢出文本
      }

效果

代码如下:

import 'package:flutter/material.dart';
class BaseWidget_Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final String _title = 'Hellow Fultter';
    final String _author = 'YYFast';
    final String _des =
        '额粉红色皇甫嵩恶化烦死额混复搜红额粉红色皇甫嵩恶化烦死额我还是foe耦合foe回复搜嗯好佛森分红额粉红色皇甫嵩恶化烦死额';
    return Container(
        height: 500,
        width: 621,
        color: Colors.red[100],
        child: Column(
          children: <Widget>[
            Text(
              '$_title\n$_author\n$_des',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 18,
                color: Colors.black87,
              ),
              maxLines: 4, //最大行数
              overflow: TextOverflow.clip,
            ),
            Container(height: 20),
            Text(
              '$_des',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 18,
                color: Colors.red,
              ),
              maxLines: 2, //最大行数
              overflow: TextOverflow.fade,
            ),
            Container(height: 20),
            Text(
              '$_des',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontStyle: FontStyle.normal,
                fontSize: 18,
                color: Colors.blue,
              ),
              maxLines: 2, //最大行数
              overflow: TextOverflow.ellipsis,
            ),
            Container(height: 20),
            Text(
              '$_des',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontStyle: FontStyle.italic,
                fontSize: 18,
                color: Colors.green,
              ),
              maxLines: 2, //最大行数
              overflow: TextOverflow.visible,
            ),
          ],
        ));
  }
}

2 富文本

Flutter中富文本使用RichText()函数创建,与普通文本不同的是可以使用TexSpan()函数,可以拼接子串,一个成员为的数组;其他基本属性使用的是普通文本Text()的基本属性:

//富文本
class RichText_Demo extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return Container(
     width: 621,
     height: 500,
     color: Colors.amber,
     child: Column(
       children: <Widget>[
         RichText(
             textAlign: TextAlign.center,
             text: TextSpan(
                 text: 'Flutter Text Test',
                 style: TextStyle(
                   backgroundColor: Colors.grey[100],
                   fontSize: 26,
                   color: Colors.green,
                 ),
                 children: <TextSpan>[
                   TextSpan(
                     text: '\n测试测试测试测试测试测试',
                     style: TextStyle(
                       backgroundColor: Colors.grey[100],
                       fontSize: 24,
                       color: Colors.blue,
                     ),
                   ),
                   TextSpan(
                     text: '\n测试测试测试测试测试测试',
                     style: TextStyle(
                       backgroundColor: Colors.grey[100],
                       fontSize: 20,
                       color: Colors.blue,
                     ),
                   ),
                   TextSpan(
                     text: '\n测试测试测试测试测试测试',
                     style: TextStyle(
                       backgroundColor: Colors.grey[100],
                       fontSize: 16,
                       color: Colors.blue,
                     ),
                   )
                 ]))
       ],
     ),
   );
 }
}

示例

3 布局

Flutter布局主要使用的是以下这3中样式

  • Row:X方向,子视图控件横向布局展现
  • Columnn:Y方向,子视图控件纵向布局展现
  • Stack:Z方向,子视图控件正向布局展现

这3种样式分别组合起来构成了Flutter的布局样式,这3中样式分别可以添加children,可以是Container,可以是Text,也可以是Icon等等…这也就使得布局丰富,样式多起来;
Flutter布局结构图

3.1 Row 和 Column

在使用Row和Cloumn布局的时候,要注意两个点:

  • 主轴方向:Row布局为水平方向;Column布局为竖直方向
  • 交叉方向:Row布局为竖直方向;Column布局为水平方向

以下示例为Row(水平布局);

  • mainAxisAlignment:主轴方向
    • center 中间对齐
    • start, 起始位置(X方向为左边left,Y方向为顶部top)
    • end,结束位置(X方向为左边right,Y方向为顶部bottom)
    • spaceAround,平局分配在之间和两边
    • spaceBetween,平均分配在之间,两边间距为0
    • spaceEvenly,等间距的

主轴start-end

主轴spaceAround-spaceBetween

  • crossAxisAlignment:交叉方向
    • center 中间对齐
    • star, 起始位置(X方向为左边left,Y方向为顶部top)
    • end,结束位置(X方向为左边right,Y方向为顶部bottom)
    • stretch,要求子视图填充交叉轴,这导致传递给子级的约束在交叉轴。
    • baseline,要与文本Text配合使用,控件的文本底部基准线必须对齐,使用较少

交叉轴start-end

代码如下:

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.blue,
        alignment: Alignment(0, 0),
        child:
            Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
			          Container(child: Icon(Icons.add, size: 120), color: Colors.red),
			          Container(child: Icon(Icons.add_a_photo, size: 80), color: Colors.green),
			          Container(child: Icon(Icons.add_alarm, size: 60), color: Colors.white),  
                    Text('主轴-spaceBetween'),
        ]));
  }
}

3.2 Stack

在使用Stack布局,也称为层级布局的时候,主要使用到了三个个控件:

  • AspectRatio :比例,相对于父控件的比例

  • Alignment :相对于中心点(0,0)的位置,取值为 -1 ~ 1,为比例值,如下图示例:
    当Alignment取值为(0,0)时在中心位置,取其它值时如图小红块的位置;

Alignment取值示例:图中红色方块位置

  • Positioned:相对于父控件的位置,类似于相对布局。使用方式是用其将Container包装起来,用于描述Container的布局属性,位置大小等,而Container用于展示;
    • const Positioned({
      Key key,
      this.left, //距左
      this.top, //距上
      this.right, //距右
      this.bottom, //距底
      this.width, //宽度
      this.height, //高度
      })

Positioned取值示例

代码示例:
**注意:**left,right,top,bottom的取值不一定为0,可以是任意数值,根据实际布局而定

class Stack_Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment(0.0, 0.0),
      color: Colors.yellow,
      child: Stack(
        children: <Widget>[
          Container(
            height: 200,
            width: 200,
            color: Colors.blue,
          ),
          Positioned(
              left: 0,
              top: 0,
              width: 30,
              height: 30,
              child: Container(
                color: Colors.red,
              )),
          Positioned(
              right: 0,
              top: 0,
              width: 30,
              height: 30,
              child: Container(
                color: Colors.white,
              )),
          Positioned(
              bottom: 0,
              left: 0,
              width: 30,
              height: 30,
              child: Container(
                color: Colors.orange,
              )),
          Positioned(
              bottom: 0,
              right: 0,
              width: 30,
              height: 30,
              child: Container(
                color: Colors.cyan,
              ))
        ],
      ),
    );
  }
}

4 状态管理State

在Flutter控件Widget中,有两种状态:

  • StatelessWidget: 无状态控件,不需要刷新数据,更新布局等操作,不需要manager管理;
  • StatefulWidget: 有状态控件,需要刷新展示数据,更新布局等操作,需要manager管理;

在这里主要了解有状态的:StatefulWidget,因为我们开发中大部分控件或者界面都需要改变状态,比如刷新count,改变背景色,改变布局等;这时候,就需要一个manager来操作,对Widget重新build操作;


比如示例Demo中,点击右下角的按钮,中间的数字会+1,这种的就是有状态的Widget,需要一个manager来管理其状态;
示例demo

StatefulWidget代码示例:

import 'package:flutter/material.dart';

class StateMagDemon extends StatefulWidget {
  @override
  _StateMagDemonState createState() => _StateMagDemonState();
}

class _StateMagDemonState extends State<StateMagDemon> {
  int _count = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("StateManagerDemo"),
      ),
      body: Center(
        child: Chip(label: Text('$_count')),
      ),
     floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          _count++;
          setState(() {});
          print('number = $_count');
        },
      ),
    );
  }
}

注意:

  1. 在StateMagDemon()中,需要创建createState();如果传入参数还需要构造函数,为创建Widget使用;
  2. _StateMagDemonState(),用于管理数据及刷新,重新build,例如示例中的_count;
  3. 数据_count改变以后,需要调用刷新方法setState(() {}),重新built控件,来达到刷新的效果。

原文链接:链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值