likes
comments
collection
share

Flutter中10个必须掌握的widget(带详细API解释)

作者站长头像
站长
· 阅读数 4

1、文本及样式(Text)

Text用于显示简单样式文本,它包含一些控制文本显示样式的一些属性

const Text(
    this.data, {
    Key key,
    this.style,
    this.strutStyle,
    this.textAlign,
    this.textDirection,
    this.locale,
    this.softWrap,
    this.overflow,
    this.textScaleFactor,
    this.maxLines,
    this.semanticsLabel,
    this.textWidthBasis,
    this.textHeightBehavior,
  })

基础属性

属性说明
textAlign对齐:left、start、right、end、center、justify
textDirectionTextDirection.ltr:从左到右、TextDirection.rtl:从右到左
softWrap是否自动换行
overflow截取部分展示:clip:直接截取 fade:渐隐 ellipsis:省略号,省略的部分是以单词为单位,而不是字母,比如 hello worddfsa fdafafsasfs ,显示hello …
textScaleFactor字体缩放
maxLines显示到最大行数
semanticsLabel

TextStyle

属性说明
inherit是否继承父组件的属性,默认true,这个属性极少需要设置为false,设置为false字体默认为白色、10pixels
color字体颜色
fontSize字体大小,默认14
fontWeight字体粗细 一般使用的属性:FontWeight normal(默认) 、FontWeight bold(粗体)
fontStyle字体:normal和italic
fontFamily设置字体,注意和 fontStyle的区别
letterSpacing字母间距,默认0,负数间距越小,正数 间距越大
wordSpacing单词 间距,默认0,负数间距越小,正数 间距越大,注意和letterSpacing的区别,比如hello,h、e、l、l、o各是一个字母,hello是一个单词
textBaseline字体基线
height会乘以fontSize做为行高
locale设置区域,默认系统的区域
foreground前置,值是Paint,设置了foreground,color必须为null
background背景,注意是Paint
shadows阴影
decoration文字划线:下划线、上划线、中划线
decorationColor划线颜色
decorationStyle划线样式:虚线、双线等

RichText

应用程序离不开文字的展示,因此文字的排版非常重要,通常情况下Text组件可以完成绝大多数需求,它可以显示不同大小的文字、字体、颜色等,如果想在一句话或者一段文字里面显示不同样式的文字,Text组件无法满足我们的需求,这个时候需要使用RichText。

与Text不同,RichText的text属性不是String类型,而是TextSpan,TextSpan用于指定文本片段的风格及手势交互

TextSpan({
    this.style,
    this.text,
    this.children,
    this.recognizer,
    this.semanticsLabel,
  })

其中,text为String类型,用来指定文本片段,style指定该文本片段的风格,recognizer指定该文本片段的手势交互。

TextSpan是一个树状结构,children表示子节点,为List类型。每个节点代表一个文本片段,祖先节点的style对所有子孙节点起作用,当祖先节点的style中指定的值与自身节点的style发生冲突时,自身style中指定的值会覆盖掉前者

class _MyTextPage extends StatelessWidget {
  Widget _text = Text(
    "Hello Flutter",
    textDirection: TextDirection.ltr,
    style: TextStyle(
        color: Colors.red,
        fontSize: 40.0,
        fontWeight: FontWeight.bold),
  );

  Widget _richText(BuildContext context){
    return RichText(text: TextSpan(
        style: DefaultTextStyle.of(context).style,
        children:<InlineSpan>[
          TextSpan(text: '登陆即视为同意'),
          TextSpan(
              text:'《xxx服务协议》',
              style: TextStyle(color: Colors.red),
              recognizer:TapGestureRecognizer()..onTap = () {

              }
          )
        ],
    ));
  }
  
  @override
  Widget build(BuildContext context) {
    return Container(child: Column(
      children: <Widget>[
        _text,
        _richText(context)
      ]
    ));
  }
}

Flutter中10个必须掌握的widget(带详细API解释)

2、文本输入组件(TextField)

TextField是一个material design风格的输入框,本身有多种属性,除此之外装饰器InputDecoration也有多种属性,但都比较简单

TextField

const TextField({
    Key key,
    this.controller,//控制器
    this.focusNode,//焦点
    this.decoration = const InputDecoration(),//装饰
    TextInputType keyboardType,//键盘类型,即输入类型
    this.textInputAction,//键盘按钮
    this.textCapitalization = TextCapitalization.none,//大小写
    this.style,//样式
    this.strutStyle,
    this.textAlign = TextAlign.start,//对齐方式
    this.textDirection,
    this.autofocus = false,//自动聚焦
    this.obscureText = false,//是否隐藏文本,即显示密码类型
    this.autocorrect = true,//自动更正
    this.maxLines = 1,//最多行数,高度与行数同步
    this.minLines,//最小行数
    this.expands = false,
    this.maxLength,//最多输入数,有值后右下角就会有一个计数器
    this.maxLengthEnforced = true,
    this.onChanged,//输入改变回调
    this.onEditingComplete,//输入完成时,配合TextInputAction.done使用
    this.onSubmitted,//提交时,配合TextInputAction
    this.inputFormatters,//输入校验
    this.enabled,//是否可用
    this.cursorWidth = 2.0,//光标宽度
    this.cursorRadius,//光标圆角
    this.cursorColor,//光标颜色
    this.keyboardAppearance,
    this.scrollPadding = const EdgeInsets.all(20.0),
    this.dragStartBehavior = DragStartBehavior.start,
    this.enableInteractiveSelection,
    this.onTap,//点击事件
    this.buildCounter,
    this.scrollPhysics,
  }) 

InputDecoration装饰

 const InputDecoration({
    this.icon,//左侧外的图标
    this.labelText,//悬浮提示,可代替hintText
    this.labelStyle,//悬浮提示文字的样式
    this.helperText,//帮助文字
    this.helperStyle,
    this.hintText,//输入提示
    this.hintStyle,
    this.hintMaxLines,
    this.errorText,//错误提示
    this.errorStyle,
    this.errorMaxLines,
    this.hasFloatingPlaceholder = true,//是否显示悬浮提示文字
    this.isDense,
    this.contentPadding,//内填充
    this.prefixIcon,//左侧内的图标
    this.prefix,
    this.prefixText,//左侧内的文字
    this.prefixStyle,
    this.suffixIcon,//右侧内图标
    this.suffix,
    this.suffixText,
    this.suffixStyle,
    this.counter,//自定义计数器
    this.counterText,//计数文字
    this.counterStyle,//计数样式
    this.filled,//是否填充
    this.fillColor,//填充颜色
    this.errorBorder,
    this.focusedBorder,
    this.focusedErrorBorder,
    this.disabledBorder,
    this.enabledBorder,
    this.border,//边框
    this.enabled = true,
    this.semanticCounterText,
    this.alignLabelWithHint,
  })

获取输入内容

有两种方式:

  • onChanged onChanged是输入内容改变时的回调,返回一个String类型的数值,可以用一个变量记一下
TextField(
                onChanged: (text) {
                  print("输入改变时" + text);
                },
              ),
  • controller:即控制器,初始化:
var controller;
  @override
  void initState() {
    super.initState();
    controller = TextEditingController();
    controller.addListener(() {});
  }

配置给TextField

TextField(controller: controller,),

获取内容

controller.text

在事件中调用controller.text即返回输入内容。

关闭软键盘

往往我们在事件中提交的时候,是需要关闭软键盘的

这里我们就用到了focusNode

1、初始化:
FocusNode userFocusNode = FocusNode();

2、配置:
TextField(focusNode: userFocusNode,),

3、然后在需要的地方调用:
userFocusNode.unfocus();

校验

校验的话其实有个inputFormatters属性

final List<TextInputFormatter> inputFormatters;

继续看TextInputFormatter源码,有3个子类:

  • BlacklistingTextInputFormatter
  • WhitelistingTextInputFormatter
  • LengthLimitingTextInputFormatter

黑名单、白名单和长度限制,我们随便找一个看一下源码是怎么实现校验的: 往下看会看到这么一段代码:

static final BlacklistingTextInputFormatter singleLineFormatter
      = BlacklistingTextInputFormatter(RegExp(r'\n'));

关键词在RegExp,其实就是我们一般用的正则表达式而已。

这样的话,我们也可以自定义校验规则了,比如校验手机号:

String validateMobile(String value) {
    String patttern = r'(^[0-9]*$)';
    RegExp regExp = new RegExp(patttern);
    if (value.length == 0) {
      return "手机号为空";
    } else if (!regExp.hasMatch(value)) {
      return "手机号格式不正确";
    }
    return null;
  }

以上只是我们一般的校验,表单的话还是建议使用From包裹TextFormField

异常

  • 软键盘弹出之后遮盖
  • 软键盘弹出之后高度溢出 解决办法:用滑动组件包裹起来(ListView等),这样软键盘弹出的时候,输入框也会自动向上滑。

3、按钮组件

Flutter 提供了 10 多种 Button 类组件,比如 RaisedButton、FlatButton、OutlineButton、DropdownButton、RawMaterialButton、PopupMenuButton、IconButton、BackButton、CloseButton、ButtonBar、ToggleButtons等。

常见的按钮组件有:RaisedButton、FlatButton、IconButton、OutlineButton、ButtonBar、FloatingActionButton 等。

  • RaisedButton :凸起的按钮,其实就是 Material Design 风格的 Button
  • FlatButton :扁平化的按钮
  • OutlineButton:线框按钮
  • IconButton :图标按钮
  • ButtonBar:按钮组
  • FloatingActionButton:浮动按钮

常用属性

在flutter中,按钮组件有以下常用属性:

属性说明
onPressed必填参数,按下按钮时触发的回调,接收一个方法,传 null 表示按钮禁用,会显示禁用相关样式
textColor文本颜色
color文本颜色
disabledColor按钮禁用时的颜色
disabledTextColor按钮禁用时的文本颜色
splashColor点击按钮时水波纹的颜色
highlightColor点击(长按)按钮后按钮的颜色
elevation:阴影的范围,值越大阴影范围越大
shape设置按钮的形状

RaisedButton

RaisedButton是一个material风格”凸起“的按钮,基本用法:

Widget _RaisedButton = RaisedButton(
    child: Text('RaisedButton'),
    onPressed: (){
    },
  );

FlatButton

FlatButton是一个扁平的按钮,用法和RaisedButton一样,代码如下:

Widget _FlatButton = FlatButton(
    child: Text('Button'),
    color: Colors.blue,
    onPressed: () {},
  );

OutlineButton

OutlineButton 是一个带边框的按钮,用法和RaisedButton一样,代码如下:

Widget _OutlineButton = OutlineButton(
    borderSide: BorderSide(color: Colors.blue,width: 2),
    disabledBorderColor: Colors.black,
    highlightedBorderColor: Colors.red,
    child: Text('OutlineButton'),
    onPressed: () {},
  );

RawMaterialButton

RawMaterialButton是基于Semantics, Material和InkWell创建的组件,它不使用当前的系统主题和按钮主题,用于自定义按钮或者合并现有的样式,而RaisedButton和FlatButton都是基于RawMaterialButton配置了系统主题和按钮主题,相关属性可以参考RaisedButton,参数基本一样,基本用法如下

Widget _RawMaterialButton = RawMaterialButton(
    onPressed: (){},
    fillColor: Colors.blue,
    child: Text('RawMaterialButton'),
  );

IconButton

IconButton是一个图标按钮,用法如下:

Widget _IconButton = IconButton(
    tooltip: '长按显示图标',
    icon: Icon(Icons.person),
    iconSize: 30,
    color: Colors.red,
    onPressed: () {},
  );

Flutter中10个必须掌握的widget(带详细API解释)

4、单选按钮(Radio)

const Radio({
    Key key,
    @required this.value,  //是否选中
    @required this.groupValue,
    @required this.onChanged, //点击事件
    this.mouseCursor,
    this.toggleable = false,
    this.activeColor, //选中时填充颜色
    this.focusColor, //聚焦颜色
    this.hoverColor,//悬停颜色
    this.materialTapTargetSize,//内边距,默认最小点击区域为 48 * 48,MaterialTapTargetSize.shrinkWrap 为组件实际大小
    this.visualDensity,//布局紧凑设置
    this.focusNode,//焦点控制
    this.autofocus = false,//自动聚焦,默认为 false
  })

Flutter中10个必须掌握的widget(带详细API解释)

class _RadioWidgetState extends State<RadioWidget> {
  var _radioGroupValue = '语文';
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Row(
        children: <Widget>[
          Flexible(
            child: RadioListTile(
              title: Text('语文'),
              value: '语文',
              activeColor:Colors.red,
              groupValue: _radioGroupValue,
              onChanged: (value) {
                setState(() {
                  _radioGroupValue = value;
                });
              },
            ),
          ),
          Flexible(
              child: RadioListTile(
                title: Text('数学'),
                value: '数学',
                activeColor:Colors.red,
                groupValue: _radioGroupValue,
                onChanged: (value) {
                  setState(() {
                    _radioGroupValue = value;
                  });
                },
              )),
          Flexible(
              child: RadioListTile(
                title: Text('英语'),
                value: '英语',
                activeColor:Colors.red,
                groupValue: _radioGroupValue,
                onChanged: (value) {
                  setState(() {
                    _radioGroupValue = value;
                  });
                },
              )),
        ],
      )
    );
  }
}

5、滑块组件(Slider)

const Slider({
    Key key,
    @required this.value, //当前滑动条的值
    @required this.onChanged, //滑动条值改变事件,滑动中一直触发
    this.onChangeStart, //滑动条开始滑动回调
    this.onChangeEnd, //滑动条结束滑动回调
    this.min = 0.0,//最小值,默认0.0
    this.max = 1.0, //最大值,默认1.0
    this.divisions,//将滑动条几等分
    this.label, //拖动滑块时可在滑块上方显示的label
    this.activeColor, //滑动条已划过部分及滑块颜色
    this.inactiveColor, //滑动条未划过部分的颜色
    this.mouseCursor,
    this.semanticFormatterCallback,
    this.focusNode,
    this.autofocus = false,
  })

Flutter中10个必须掌握的widget(带详细API解释)

class _SliderWidgetState extends State<SliderWidget> {
  double _sliderValue = 0;
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: <Widget>[
          Text('值:$_sliderValue'),
          SizedBox(height: 10),
          Slider(
            value: _sliderValue,
            activeColor: Colors.green,
            inactiveColor: Colors.grey,
            onChanged: (v){
              setState(() {
                _sliderValue = v;
              });
            },
          )
        ],
      ),
    );
  }
}

6、开关组件(Switch)

const Switch({
    Key key,
    @required this.value,
    @required this.onChanged,
    this.activeColor,//选中时圆圈的颜色
    this.activeTrackColor,//选中时底部横条的颜色

    this.inactiveThumbColor,//未选中时圆圈的颜色
    this.inactiveTrackColor,//未选中时底部横条的颜色

    this.activeThumbImage,//选中时圆圈的图片
    this.inactiveThumbImage,//未选中时圆圈的图片

    this.materialTapTargetSize,//点击区域尺寸,padded:向四周扩展48px区域;shrinkWrap:控件区域
    this.dragStartBehavior = DragStartBehavior.start,
    })

Flutter中10个必须掌握的widget(带详细API解释)

Container(
        margin: EdgeInsets.all(30),
          child: Column(
            children: <Widget>[
              Switch(
                value: _switchValue,
                activeColor: Colors.red,
                activeTrackColor: Colors.blue,
                activeThumbImage: AssetImage('images/icon1.png',),
                onChanged: (value){
                  setState(() {
                    _switchValue = value;
                  });
                },
              ),
              Transform.scale(
                scale: 2.0,
                child: Switch(
                    value: _switchValue,
                    onChanged: (bool) {

                    }),
              )
            ],
          ),
      ),
    );

7、进度条组件

LinearProgressIndicator 进度条组件主要有三个

  • LinearProgressIndicator 直线型进度条
  • CircularProgressIndicator 圆形进度条
  • CupertinoActivityIndicator IOS风格进度条
const LinearProgressIndicator({
    Key key,
    // [0,1] 的浮点数,用来表示进度多少,0 表示无进度,1 表示进度已完成。
    // 如果 value 为 null,则显示一个动画,否则显示一个定值 
    double value, 
    // 进度条背景颜色,默认颜色 ThemeData.backgroundColor
    Color backgroundColor,
    // Animation 类型的参数,用来设定进度值的颜色,默认颜色 ThemeData.accentColor,如果想自定义颜色,
    // 则使用 AlwaysStoppedAnimation<Color>(color)
    Animation<Color> valueColor, 
    String semanticsLabel,
    String semanticsValue,
  })

Flutter中10个必须掌握的widget(带详细API解释)

Column(
         children: <Widget>[
           SizedBox(height: 50),
           LinearProgressIndicator(
             value: 0.3,
             backgroundColor: Colors.greenAccent,
             valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
           ),
           SizedBox(height: 50),
           CircularProgressIndicator(
             value: 0.3,
             backgroundColor: Colors.greenAccent,
             valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
           ),
           SizedBox(height: 50),
           CupertinoActivityIndicator(
             radius: 10,
           )
         ],
       ),

8、图片组件

图片组件是Flutter基础组件之一,和文本组件一样必不可少。图片组件包含Image和Icon两个组件,本质上Icon不属于图片组件,但其外形效果上类似于图片。 在项目中建议优先使用Icon组件,Icon本质上是一种字体,只不过显示的不是文字,而是图标,而Image组件先通过图片解码器将图片解码,所以Icon有如下优点:

  • 通常情况下,图标比图片体积更小,显著的减少App包体积。
  • 图标不会出现失真或者模糊的现象,例如将20x20的图片,渲染在200x200的屏幕上,图片会失真或模糊,而图标是矢量图,不会失真,就像字体一样。
  • 多个图标可以存放在一个文件中,方便管理。
  • 全平台通用。

1、Image

Flutter 提供了显示图片的控件Image。并且有多种构造函数。

  • new Image 从ImageProvider获取图片
  • new Image.asset 加载asset项目资源中的文件
  • new Image.network 从URL获取网络图片
  • new Image.file 从File获取本地文件图片
  • new Image.memory 加载Uint8List 的图片

图片的支持格式:JPEG, PNG, GIF, 动画GIF, WebP, 动画WebP, BMP, WBMP

基础用法

new Image(image: new AssetImage('images/logo.png'));
new Image(image: new NetworkImage('http://www.baid.com/sports/201/pKtl744393.jpg'))

Image.network 有的时候我们需要使用一个占位图或者图片加载出错时显示某张特定的图片,这时候需要用到 FadeInImage 这个组件:

new FadeInImage.assetNetwork(
    placeholder: 'images/logo.png',
    image: imageUrl,
    width: 120,
    fit: BoxFit.fitWidth,
)
new FadeInImage.memoryNetwork(
    placeholder: kTransparentImage,
    image: imageUrl,
    width: 120,
    fit: BoxFit.fitWidth,
)

第一种方法是加载一个本地的占位图,第二种是加载一个透明的占位图,但是需要注意的是,这个组件是不可以设置加载出错显示的图片的;但是我们还可以使用第三中方法package 的 CachedNetworkImage 组件

new CachedNetworkImage(
    width: 120,
    fit: BoxFit.fitWidth,
    placeholder: new CircularProgressIndicator(),
    imageUrl: imageUrl,
    errorWidget: new Icon(Icons.error),

Image.file 加载本地的一个图片文件,比如相册的图片

new Image.file(new File('/storage/xxx/xxx/test.jpg'))

Image.memory

new Image.memory(bytes),

Image的常用属性

child: new Image.asset(
      'images/2-normal.png',
      alignment: Alignment.center,
      color: Colors.green,
      colorBlendMode: BlendMode.dstATop,
      fit: BoxFit.contain,
    ),

1、alignment 对齐方式

  • topCenter:顶部居中对齐
  • topLeft:顶部左对齐
  • topRight:顶部右对齐
  • center:水平垂直居中对齐
  • centerLeft:垂直居中水平居左对齐
  • centerRight:垂直居中水平居右对齐
  • bottomCenter底部居中对齐
  • bottomLeft:底部居左对齐
  • bottomRight:底部居右对齐

2、color和colorBlendMode

一般配合使用,BlendMode, 为混合模式的意思。

3、fit 图片拉伸

fit属性用来控制图片的拉伸和挤压,这都是根据父容器来的。

  • BoxFit.fill:全图显示,图片会被拉伸,并充满父容器。
  • BoxFit.contain:全图显示,显示原比例,可能会有空隙。
  • BoxFit.cover:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)。
  • BoxFit.fitWidth:宽度充满(横向充满),显示可能拉伸,可能裁切。
  • BoxFit.fitHeight :高度充满(竖向充满),显示可能拉伸,可能裁切。
  • BoxFit.scaleDown:效果和contain差不多,但是此属性不允许显示超过源图片大小,可小不可大。

4、repeat 是否重复

  • ImageRepeat.repeat : 横向和纵向都进行重复,直到铺满整个画布。
  • ImageRepeat.repeatX: 横向重复,纵向不重复。
  • ImageRepeat.repeatY:纵向重复,横向不重复。

5、centerSlice

当图片需要被拉伸显示的时候,centerSlice定义的矩形区域会被拉伸,可以理解成我们在图片内部定义来一个点9文件用作拉伸。也就是说只有在显示大小大于原图大小的情况下,才允许使用这个属性,否则会报错。

Image image = new Image.asset(
    'imgs/logo.jpeg',
    width: 500.0,
    height: 500.0,
    fit: BoxFit.contain,
    centerSlice: new Rect.fromCircle(center: const Offset(100.0, 100.0), radius: 10.0 ),
);

6、matchTextDirection

与Directionality配合使用实现图片反转显示

new Directionality(
          textDirection: TextDirection.rtl,
          child: Image.asset(
            'images/dress.png',
            width: 800,
            height: 900,
            matchTextDirection: true,
          ),
        )
    Image(
          image: new AssetImage('images/dress.png'),
    )

7、gaplessPlayback

当ImageProvider发生变化后,重新加载图片的过程中,原图片的展示是否保留。若值为true,保留,若为false,不保留,直接空白等待下一张图片加载。

2、Icon

Icon是图标组件,Icon不具有交互属性,如果想要交互,可以使用IconButton。

Icon(Icons.add),

设置图标的大小和颜色:

Icon(
  Icons.add,
  size: 40,
  color: Colors.red,
)

9、shape边框组件

Flutter中很多组件都有一个叫做shape的属性,类型是ShapeBorder,比如Button类、Card等组件,shape表示控件的形状,系统已经为我们提供了很多形状,对于没有此属性的组件,可以使用 Clip 类组件进行裁减

Border

Border允许单独设置每一个边上的线条样式

const Border({
    this.top = BorderSide.none,
    this.right = BorderSide.none,
    this.bottom = BorderSide.none,
    this.left = BorderSide.none,
  })
RaisedButton(
        shape: Border(
            top: BorderSide(color: Colors.red,width: 2)
        ),
        child: Text('Border'),
      ),

Flutter中10个必须掌握的widget(带详细API解释)

CircleBorder

Container(
      width: 100,
      height: 100,
      child: RaisedButton(
        shape: CircleBorder(
            side:BorderSide(color: Colors.red)
        ),
        child: Text('Border',),
      ),
    );

Flutter中10个必须掌握的widget(带详细API解释)

ContinuousRectangleBorder

连续的圆角矩形,直线和圆角平滑连续的过渡,和RoundedRectangleBorder相比,圆角效果会小一些。

Container(
      width: 300,
      height: 100,
      child: RaisedButton(
        shape: ContinuousRectangleBorder(
            side: BorderSide(color: Colors.red),
            borderRadius: BorderRadius.circular(20)),
        child: Text('ContinuousRectangleBorder',),
      ),
    );

Flutter中10个必须掌握的widget(带详细API解释)

RoundedRectangleBorder

圆角矩形

Container(
      width: 300,
      height: 100,
      child: RaisedButton(
        shape: RoundedRectangleBorder(
            side: BorderSide(color: Colors.red,width: 2),
            borderRadius: BorderRadius.circular(10)),
        child: Text('RaisedButton',),
      ),
    );

StadiumBorder

类似足球场的形状,两边圆形,中间矩形

Container(
    width: 200,
    height: 50,
    child: RaisedButton(
      shape: StadiumBorder(),
      child: Text('RaisedButton'),
    ),
  );

Flutter中10个必须掌握的widget(带详细API解释)

ClipRect

ClipRect组件使用矩形裁剪子组件,通常情况下,ClipRect作用于CustomPaint 、 CustomSingleChildLayout 、 CustomMultiChildLayout 、 Align 、 Center 、 OverflowBox 、 SizedOverflowBox组件,例如ClipRect作用于Align,可以仅显示上半部分,代码如下:

ClipRect(
    child: Align(
      alignment: Alignment.topCenter,
      heightFactor: 0.5,
      child: Container(
        height: 150,
        width: 150,
        child: Image.asset(
          'images/cat.png',
          fit: BoxFit.cover,
        ),
      ),
    ),
  );

原图效果

Flutter中10个必须掌握的widget(带详细API解释)

剪切后 Flutter中10个必须掌握的widget(带详细API解释)

clipper参数定义裁剪规则,下面具体介绍。

clipBehavior参数定义了裁剪的方式,只有子控件超出父控件的范围才有裁剪的说法,各个方式说明如下:

  • none:不裁剪,系统默认值,如果子组件不超出边界,此值没有任何性能消耗。
  • hardEdge:裁剪但不应用抗锯齿,速度比none慢一点,但比其他方式快。
  • antiAlias:裁剪而且抗锯齿,此方式看起来更平滑,比antiAliasWithSaveLayer快,比hardEdge慢,通常用于处理圆形和弧形裁剪。
  • antiAliasWithSaveLayer:裁剪、抗锯齿而且有一个缓冲区,此方式很慢,用到的情况比较少。

ClipRRect

ClipRRect组件可以对子组件进行圆角裁剪,默认圆角半径为0

ClipRRect(
    borderRadius: BorderRadius.circular(30),
    child: Container(
      height: 150,
      width: 150,
      color: red,
      child: Image.asset(
        'images/cat.png',
        fit: BoxFit.cover,
      ),
    ),
  );

Flutter中10个必须掌握的widget(带详细API解释)

ClipPath

ClipPath组件根据路径进行裁剪,我们自定义裁剪路径也可以使用系统提供的

ClipPath.shape(
    shape: StadiumBorder(),
    child: Container(
      height: 250,
      width: 250,
      color: red,
      child: Image.asset(
        'images/cat.png',
        fit: BoxFit.cover,
      ),
    ),
  );

shape参数是ShapeBorder类型,系统已经定义了很多形状,介绍如下:

  • RoundedRectangleBorder:圆角矩形
  • ContinuousRectangleBorder:直线和圆角平滑连续的过渡,和RoundedRectangleBorder相比,圆角效果会小一些。
  • StadiumBorder:类似于足球场的形状,两端半圆。
  • BeveledRectangleBorder:斜角矩形
  • CircleBorder:圆形。

CustomClipper

CustomClipper并不是一个组件,而是一个abstract(抽象)类,使用CustomClipper可以绘制出任何我们想要的形状

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: ClipPath(
        clipper: TrianglePath(),
        child: Container(
          height: 200,
          width: 200,
          color: Colors.red,
        ),
      ),
    );
  }
}

class TrianglePath extends CustomClipper<Path>{
  @override
  Path getClip(Size size) {
    var path = Path();
    path.moveTo(size.width/2, 0);
    path.lineTo(0, size.height);
    path.lineTo(size.width, size.height);
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return true;
  }
}


Flutter中10个必须掌握的widget(带详细API解释)

10、标签组件(RawChip)

Material风格标签控件,此控件是其他标签控件的基类,通常情况下,不会直接创建此控件,而是使用如下控件:

  • Chip:Chip是一个简单的标签控件,仅显示信息和删除相关属性,是一个简化版的RawChip
  • InputChip:以紧凑的形式表示一条复杂的信息,例如实体(人,地方或事物)或对话文本
  • ChoiceChip:允许从一组选项中进行单个选择,创建一个类似于单选按钮的标签,本质上ChoiceChip也是一个RawChip,ChoiceChip本身不具备单选属性。
  • FilterChip:FilterChip可以作为过滤标签
  • ActionChip:显示与主要内容有关的一组动作
Chip({	
    Key key,	
    this.avatar,//左侧Widget,一般为小图标	
    @required this.label,//标签	
    this.labelStyle,	
    this.labelPadding,	
    this.deleteIcon//删除图标	
    this.onDeleted//删除回调,为空时不显示删除图标	
    this.deleteIconColor//删除图标的颜色	
    this.deleteButtonTooltipMessage//删除按钮的tip文字	
    this.shape//形状	
    this.clipBehavior = Clip.none,	
    this.backgroundColor//背景颜色	
    this.padding, // padding	
    this.materialTapTargetSize//删除图标material点击区域大小	

  })

Flutter中10个必须掌握的widget(带详细API解释)

class _ChipWidgetState extends State<ChipWidget> {
  int _selectIndex = 0;
  @override
  Widget build(BuildContext context) {
    return Wrap(
      spacing: 15,
      children: List.generate(10, (index) {
        return ChoiceChip(
          label: Text('Chip $index'),
          selected: _selectIndex == index,
          selectedColor: red,
          onSelected: (v) {
            setState(() {
              _selectIndex = index;
            });
          },
        );
      }).toList(),
    );
  }
}

代码地址:github.com/SunshineBro…