basic.dart

basic.dart

[TOC]

  • basic.dart这个文件按对子节点的影响大致分成了6种Widget。
  • 按子节点的数量,可以分为SingleChildRenderObjectWidgetMultiChildRenderObjectWidget。也就是布局Widget与普通Widget的区别。相当于android中的ViewGroupView吧。

PAINTING NODES

对子节点施加额外的painting的效果,透明度、阴影、边角剪裁等。

Opacity

  • 改变子节点的不透明度,效果图:
    basic.dart_第1张图片
    opacity

    源码:

import 'package:flutter/material.dart';

class OpacityDemo extends StatefulWidget {
  @override
  _OpacityDemoState createState() {
    return _OpacityDemoState();
  }
}

class _OpacityDemoState extends State {
  double _opacity = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('OpacityDemo')),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Slider(
            value: _opacity,
            onChanged: (value) => setState(() => _opacity = value),
          ),
          Opacity(
            // 只有一个不透明度的参数,动态设置即可实现动画
            opacity: _opacity,
            child: Container(
              width: 200.0,
              height: 200.0,
              color: Colors.red,
            ),
          ),
        ],
      ),
    );
  }
}
  • Opacity的实现方式是先把子节点绘制到一个缓存中,然后把设置好的透明度与子节点混合(blend)。
  • 当不透明度为0和1的时候,效率会高一些,因为没了把子节点绘制到缓存中的步骤。
  • 跟动态添加或删除widget相比,设置不透明度(1或0)的效率要更高。
  • 如果要做不透明度的动画,使用AnimatedOpacity的效率要高很多,因为动态设置Opacity的不透明度会触发每一帧的刷新,而AnimatedOpacity不会。

ShaderMask

  • 用shader给子节点增加一个mask。效果图:
    basic.dart_第2张图片
    ShaderMas

    源码:

import 'package:flutter/material.dart';

class ShaderMaskDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ShaderMask(
        shaderCallback: (Rect bounds) {
          return RadialGradient(
            center: Alignment.topLeft,
            colors: [Colors.yellow, Colors.deepOrange.shade900],
            tileMode: TileMode.mirror,
          ).createShader(bounds);
        },
        child: Center(child: Text('I’m burning the memories')),
      ),
    );
  }
}
  • RadialGradientcreateShader方法来自Gradient类,也就说只有Gradient的子类才能创建Shader
  • 这个Widget目前来看用的人还是比较少,github上相关的Issue也只有个位数。
  • 看了下Gradient是继承了Shader类的。

BackdropFilter

  • 主要的一个应用是ios风格的毛玻璃效果。效果图:
    basic.dart_第3张图片
    BackdropFilter

    源码:

import 'package:flutter/material.dart';
import 'dart:ui' as ui;

class BackdropFilterDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          ConstrainedBox(
              constraints: BoxConstraints.expand(), child: FlutterLogo()),
          BackdropFilter(
            filter: ui.ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
            child: Center(
              child: Text(
                'Frosted',
                style: Theme.of(context).textTheme.display3,
              ),
            ),
          ),
        ],
      ),
    );
  }
}
  • BackdropFilter服务的对象应该是在它“后面”的那些Widget,而它的child只是借用了一下它的效果(让BackdropFilter以及child在“后面”的Widget基础之上产生毛玻璃效果)。
  • 最终产生毛玻璃效果的区域是child的区域。
  • 有一点搞不懂的是这里用的Text的毛玻璃的区域,为什么是不对称的?

CustomPaint

// TODO

ClipRect

  • 把子节点的形状剪成矩形,不过一般的子节点都看不出来,因为大部分本身就是矩形的吧。效果图:
    basic.dart_第4张图片
    ClipRect

    源码:

import 'package:flutter/material.dart';

class ClipRectDemo extends StatefulWidget {
  @override
  _ClipRectDemoState createState() {
    return _ClipRectDemoState();
  }
}

class _ClipRectDemoState extends State {
  double _heightFactor = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('ClipRectDemo')),
      body: Column(
        children: [
          Slider(
            value: _heightFactor,
            onChanged: (value) => setState(() => _heightFactor = value),
          ),
          ClipRect(
            // Align设置了heightFactor, 那么Align的高度为Container的_heightFactor倍
            // ClipRect之后, Container的下半部分就被剪掉了
            child: Align(
              alignment: AlignmentDirectional.topCenter,
              heightFactor: _heightFactor,
              // Container的大小为整个body
              child: Container(
                height: 400.0,
                color: Colors.red,
              ),
            ),
          ),
        ],
      ),
    );
  }
}
  • 默认情况ClipRect会禁止子节点超出它本身,但是可以通过自定义clipper属性来实现超出ClipRect的情况。clipper可以移动要剪的位置和大小,也就是那个Rect。自定义clipper单独发篇文章好了。

ClipRRect

  • 作用和ClipRect一样,只不过有一个borderRadius参数,可以控制矩形的圆角,效果图:
    basic.dart_第5张图片
    ClipRRect

    源码:
import 'package:flutter/material.dart';

class ClipRRectDemo extends StatefulWidget {
  @override
  _ClipRRectDemoState createState() {
    return _ClipRRectDemoState();
  }
}

class _ClipRRectDemoState extends State {
  double _cornerRadius = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('ClipRRectDemo')),
      body: Column(
        children: [
          Slider(
            value: _cornerRadius,
            onChanged: (value) => setState(() => _cornerRadius = value),
          ),
          ClipRRect(
            // 控制圆角的角度
            borderRadius: BorderRadius.circular(_cornerRadius * 180),
            child: Container(
              height: 400.0,
              color: Colors.red,
            ),
          ),
        ],
      ),
    );
  }
}

ClipOval

  • ClipOval就是ClipRRect的圆角成90°的情况
    源码:
import 'package:flutter/material.dart';

class ClipOvalDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('ClipOvalDemo')),
      body: ClipOval(
        child: Container(
          height: 400.0,
          color: Colors.red,
        ),
      ),
    );
  }
}

ClipPath

  • ClipPath默认的行为(clipper参数为空)与ClipRect一样,就是简单的矩形。那么也就可知Clip系列Widget就是ClipPath的特殊情况。
  • clipper放到proxy_box.dart再分析了。
    效果图:
    basic.dart_第6张图片
    ClipPath

    源码:
import 'package:flutter/material.dart';

class ClipPathDemo extends StatefulWidget {
  @override
  _ClipPathDemoState createState() {
    return _ClipPathDemoState();
  }
}

class _ClipPathDemoState extends State {
  double _heightFactor = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('ClipRectDemo')),
      body: Column(
        children: [
          Slider(
            value: _heightFactor,
            onChanged: (value) => setState(() => _heightFactor = value),
          ),
          ClipPath(
            // Align设置了heightFactor, 那么Align的高度为Container的0.5倍
            // ClipRect之后, Container的下半部分就被剪掉了
            child: Align(
              alignment: AlignmentDirectional.topCenter,
              heightFactor: _heightFactor,
              // Container的大小为整个body
              child: Container(
                height: 400.0,
                color: Colors.red,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

PhysicalModel

  • PhysicalModel的一个主要作用就是给子节点添加阴影效果(由elevation指定),还可以指定阴影的颜色和子节点的形状,主要的功能就这几个。效果图:
    basic.dart_第7张图片
    PhysicalModel

    源码:
import 'package:flutter/material.dart';

class PhysicalModelDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('PhysicalModelDemo')),
      body: PhysicalModel(
        color: Colors.red,
        shape: BoxShape.circle,
        shadowColor: Colors.blueAccent,
        elevation: 20.0,
        child: Container(),
      ),
    );
  }
}

PhysicalShape

  • PhysicalShapePhysicalModel类似,只不过可以自定义path(即clipper参数)。

POSITIONING AND SIZING NODES

  • 控制子节点的位置和大小

Transform

  • 给子节点做一个变换,注意是静态的变换(也就是变换应用了之后再画出来),而不是动画!效果图:
    basic.dart_第8张图片
    Transform

源码:

import 'package:flutter/material.dart';

class TransformDemo extends StatefulWidget {
  @override
  TransformDemoState createState() {
    return TransformDemoState();
  }
}

class TransformDemoState extends State {
  double _angle = 0.0;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Scaffold(
        appBar: AppBar(title: Text('TransformDemo')),
        body: Column(
          children: [
            Slider(
              value: _angle,
              onChanged: (value) => setState(() => _angle = value),
            ),
            Transform.rotate(
              alignment: AlignmentDirectional.center,
              angle: _angle,
              child: Center(
                child: Container(
                  height: 200.0,
                  width: 200.0,
                  color: Colors.red,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

CompositedTransformTarget

// TODO

CompositedTransformFollower

// TODO

FittedBox

  • 提供了子节点在FittedBox中展示的几种策略,分别是fill(子节点长和宽都撑满父节点),contain(子节点包含在父节点中),cover(子节点覆盖住父节点所占的区域,但是不像fill那样拉伸,而是通过剪裁然后放大的方式实现覆盖),fitHeight(按子节点的高度撑满父节点,宽度不管它),fitWidth(按子节点的宽度撑满父节点,高度不管它),none(按原图显示),scaleDown(如果图片需要缩小的话,那么就跟contain效果一样,其他情况和none效果一样)。效果图:
    FittedBox

    源码:
import 'package:flutter/material.dart';

class FittedBoxDemo extends StatefulWidget {
  @override
  FittedBoxDemoState createState() {
    return FittedBoxDemoState();
  }
}

class FittedBoxDemoState extends State {
  BoxFit _fit = BoxFit.cover;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('FittedBoxDemo')),
      body: Column(
        children: [
          Row(
            children: [
              RaisedButton(
                onPressed: () {
                  setState(() => _fit = BoxFit.fill);
                },
                child: Text('fill'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() => _fit = BoxFit.contain);
                },
                child: Text('contain'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() => _fit = BoxFit.cover);
                },
                child: Text('cover'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() => _fit = BoxFit.fitWidth);
                },
                child: Text('fitWidth'),
              ),
            ],
          ),
          Row(
            children: [
              RaisedButton(
                onPressed: () {
                  setState(() => _fit = BoxFit.fitHeight);
                },
                child: Text('fitHeight'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() => _fit = BoxFit.none);
                },
                child: Text('none'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() => _fit = BoxFit.scaleDown);
                },
                child: Text('scaleDown'),
              ),
            ],
          ),
          Center(
            child: Container(
              height: 200.0,
              width: 200.0,
              color: Colors.red,
              child: FittedBox(
                fit: _fit,
                child: Image.asset('assets/rabbit.png'),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

FractionalTranslation

  • 依据子节点自身的百分比来对子节点做出变换。效果图:
    basic.dart_第9张图片
    FractionalTranslation

    源码:

import 'package:flutter/material.dart';

class FractionalTranslationDemo extends StatefulWidget {
  @override
  FractionalTranslationDemoState createState() {
    return FractionalTranslationDemoState();
  }
}

class FractionalTranslationDemoState extends State {
  double _offset = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('FractionalTranslationDemo')),
      body: Column(
        children: [
          Slider(
            value: _offset,
            onChanged: (value) => setState(() => _offset = value),
          ),
          Container(
            color: Colors.blueAccent,
            child: GestureDetector(
              onTap: () => print('tapped!!!!'),
              child: FractionalTranslation(
                transformHitTests: true,
                translation: Offset(_offset, _offset),
                child: Container(
                  height: 200.0,
                  width: 200.0,
                  color: Colors.red,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
  • 有一点需要注意的是transformHitTests参数,这个参数表示接收hit test的区域是否也跟着Transition一起走。

RotatedBox

  • 以90°为单位对子节点进行旋转。效果图:
    basic.dart_第10张图片
    RotatedBox

    源码:

import 'package:flutter/material.dart';

class RotatedBoxDemo extends StatefulWidget {
  @override
  RotatedBoxDemoState createState() {
    return new RotatedBoxDemoState();
  }
}

class RotatedBoxDemoState extends State {
  int turns = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('RotatedBoxDemo')),
      body: GestureDetector(
        onTap: () {
          setState(() => ++turns);
        },
        child: RotatedBox(
          quarterTurns: turns,
          child: Center(
            child: Image.asset('assets/rabbit.png'),
          ),
        ),
      ),
    );
  }
}
  • quarterTurns可以一直累加,它自己会做判断。

Padding

  • 给子节点增加(其实是外边距吧)padding。效果图:
    basic.dart_第11张图片
    Padding

    源码:

import 'package:flutter/material.dart';

class PaddingDemo extends StatefulWidget {
  @override
  PaddingDemoState createState() {
    return new PaddingDemoState();
  }
}

class PaddingDemoState extends State {
  double _insets = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('PaddingDemo')),
      body: Column(
        children: [
          Slider(
            value: _insets,
            onChanged: (value) => setState(() => _insets = value),
          ),
          Container(
            color: Colors.blueAccent,
            child: Center(
              child: Padding(
                padding: EdgeInsets.all(_insets * 50.0),
                child: Container(
                  width: 200.0,
                  height: 200.0,
                  color: Colors.red,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
  • 关于直接使用Padding和使用Containerpadding属性来构造padding,实际上如果Container只设置了padding属性的话,那么构造出来的就是单纯的PaddingContainer只是一个便利的控件而已。

Align

  • 对子节点进行对齐的控件。效果图:
    Align

    源码:

import 'package:flutter/material.dart';

class AlignDemo extends StatefulWidget {
  @override
  AlignDemoState createState() {
    return new AlignDemoState();
  }
}

class AlignDemoState extends State {
  AlignmentDirectional _directional = AlignmentDirectional.center;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('AlignDemo')),
      body: Column(
        children: [
          GridView.count(
            crossAxisCount: 3,
            shrinkWrap: true,
            childAspectRatio: 3.0,
            crossAxisSpacing: 8.0,
            mainAxisSpacing: 8.0,
            children: [
              RaisedButton(
                onPressed: () {
                  setState(() {
                    _directional = AlignmentDirectional.topStart;
                  });
                },
                child: Text('topStart'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() {
                    _directional = AlignmentDirectional.topCenter;
                  });
                },
                child: Text('topCenter'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() {
                    _directional = AlignmentDirectional.topEnd;
                  });
                },
                child: Text('topEnd'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() {
                    _directional = AlignmentDirectional.centerStart;
                  });
                },
                child: Text('centerStart'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() {
                    _directional = AlignmentDirectional.center;
                  });
                },
                child: Text('center'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() {
                    _directional = AlignmentDirectional.centerEnd;
                  });
                },
                child: Text('centerEnd'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() {
                    _directional = AlignmentDirectional.bottomStart;
                  });
                },
                child: Text('bottomStart'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() {
                    _directional = AlignmentDirectional.bottomCenter;
                  });
                },
                child: Text('bottomCenter'),
              ),
              RaisedButton(
                onPressed: () {
                  setState(() {
                    _directional = AlignmentDirectional.bottomEnd;
                  });
                },
                child: Text('bottomEnd'),
              ),
            ],
          ),
          Expanded(
            child: Center(
              child: Align(
                alignment: _directional,
                child: Text(
                  'i am text',
                  style: Theme.of(context).textTheme.headline,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
  • Align有个widthFactorheightFactor,它们的作用是确定Align本身的大小,Align的大小(如果设置了*Factor)会是子节点的宽/高*factor,比如说如果子节点宽100,widthFactor为2.0的话,那么Align自身的宽度就为200.0,高度同理。
  • 如果factor没有设置,且有约束(?什么意思)的话,那么Align会尽可能的大
  • 如果没有约束,且factor为null的话,那么Align就是子节点的大小。

Center

  • Center没什么好讲的,算是最常用的几种Widget之一了,就是Align的一个特殊情况/别名,它本身也是继承了Align类,它的widthFactorheightFactorAlign的一样。效果图:
    basic.dart_第12张图片
    Center

    源码:
import 'package:flutter/material.dart';

class CenterDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('CenterDemo')),
      body: Center(
        child: Text('i am in center'),
      ),
    );
  }
}

CustomSingleChildLayout

  • [SingleChildLayoutDelegate]没有对外开放的已实现的实现类, flutter内建的实现类(但是是private的)的有(包括但不限于): _ToolbarContainerLayout(这个appbar内部使用的)。也就是说要用[CustomSingleChildLayout]的话, 就需要自己去实现[SingleChildLayoutDelegate]这里暂时就不去搞了。

LayoutId

// TODO

CustomMultiChildLayout

// TODO

SizedBox

  • 强制子节点拥有SizedBox指定的大小。效果图:
    basic.dart_第13张图片
    SizedBox

    源码:
import 'package:flutter/material.dart';

class SizedBoxDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('SizedBoxDemo')),
      body: Center(
        child: SizedBox(
          width: 200.0,
          height: 200.0,
          child: Container(
            color: Colors.red,
          ),
        ),
      ),
    );
  }
}
  • SizedBox有个expand命名构造函数,调用这个构造函数的时候,会生成一个撑满父节点的SizedBox

ConstrainedBox

  • 对子节点施加额外的约束,但是所谓的最大(小)宽(高)度,到底是以什么策略进行变换还是搞不清楚。之后涉及到BoxConstraint的时候再来细看吧。效果图:
    basic.dart_第14张图片
    ConstrainedBox

    源码:
import 'package:flutter/material.dart';

class ConstrainedBoxDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('ConstrainedBoxDemo')),
      body: Column(
        children: [
          Flexible(
            child: Container(
              color: Colors.blueAccent,
            ),
          ),
          ConstrainedBox(
            constraints: BoxConstraints(minHeight: 100.0, maxHeight: 200.0),
            child: Container(
              color: Colors.red,
            ),
          ),
        ],
      ),
    );
  }
}

UnconstrainedBox

// TODO

FractionallySizedBox

  • 对子节点施加一个百分比,这个百分比是FractionallySizedBox的可用空间的百分比。比较适合那种一个按钮占据一行的场景,可以设置按钮以屏幕宽为基准进行百分比缩小,这样的话在不同尺寸的设备上适应性会比较好。效果图:
    basic.dart_第15张图片
    FractionallySizedBox

    源码:
import 'package:flutter/material.dart';

class FractionallySizedBoxDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('FractionallySizedBoxDemo')),
      body: Container(
        color: Colors.blueAccent,
        constraints: BoxConstraints.expand(),
        child: Column(
          children: [
            FractionallySizedBox(
              widthFactor: 0.5,
              child: RaisedButton(
                onPressed: () {},
                child: Text('child1'),
              ),
            ),
            SizedBox(height: 8.0),
            FractionallySizedBox(
              widthFactor: 0.8,
              child: RaisedButton(
                onPressed: () {},
                child: Text('child2'),
              ),
            ),
            SizedBox(height: 8.0),
            FractionallySizedBox(
              widthFactor: 0.6,
              child: RaisedButton(
                onPressed: () {},
                child: Text('child2'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

LimitedBox

// TODO

OverflowBox

// TODO

SizedOverflowBox

// TODO

Offstage

// TODO

_OffstageElement

// TODO

AspectRatio

// TODO

IntrinsicWidth

// TODO

IntrinsicHeight

// TODO

Baseline

// TODO

SLIVERS

SliverToBoxAdapter

// TODO

SliverPadding

// TODO

LAYOUT NODES

ListBody

// TODO

Stack

// TODO

IndexedStack

// TODO

Positioned

// TODO

PositionedDirectional

// TODO

Flex

// TODO

Row

// TODO

Column

// TODO

Flexible

// TODO

Expanded

// TODO

Wrap

// TODO

Flow

// TODO

RichText

// TODO

RawImage

// TODO

DefaultAssetBundle

// TODO

WidgetToRenderBoxAdapter

// TODO

EVENT HANDLING

Listener

// TODO

RepaintBoundary

// TODO

IgnorePointer

  • 此节点以及其子节点都将忽略点击事件,用ignoring参数区分是否忽略。效果图:
    IgnorePointer

    源码:
import 'package:flutter/material.dart';

class IgnorePointerDemo extends StatefulWidget {
  @override
  _IgnorePointerDemoState createState() {
    return _IgnorePointerDemoState();
  }
}

class _IgnorePointerDemoState extends State {
  bool _ignore = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('IgnorePointerDemo')),
      body: Container(
        color: Colors.red,
        alignment: AlignmentDirectional.center,
        child: Column(
          children: [
            Switch(
              value: _ignore,
              onChanged: (value) {
                setState(() => _ignore = value);
              },
            ),
            IgnorePointer(
              ignoring: _ignore,
              child: RaisedButton(
                onPressed: () => print('clicked!!'),
                child: Text('ignore'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
  • switch开关控制了是否忽略点击事件。

AbsorbPointer

  • 这个控件会absorb(吸收)掉点击事件,跟其他框架里的swallow(吞)是一个意思吧。这个控件和上个控件的区别在于,这个控件本身是能够响应点击事件的,它做的是阻止事件传播到它的子节点上去,而IgnorePointer本身也不再接收事件了。效果图:
    AbsorbPointer

    源码:
import 'package:flutter/material.dart';

class AbsorbPointerDemo extends StatefulWidget {
  @override
  _AbsorbPointerDemo createState() {
    return _AbsorbPointerDemo();
  }
}

class _AbsorbPointerDemo extends State {
  bool _absorb = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('AbsorbPointerDemo')),
      body: Container(
        color: Colors.red,
        alignment: AlignmentDirectional.center,
        child: Column(
          children: [
            Switch(
              value: _absorb,
              onChanged: (value) {
                setState(() => _absorb = value);
              },
            ),
            GestureDetector(
              onTap: () => print('tap in GestureDetector'),
              child: AbsorbPointer(
                absorbing: _absorb,
                child: RaisedButton(
                  onPressed: () => print('tap in RaisedButton'),
                  child: Text('absorb'),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
  • GestureDetector的响应反映AbsorbPointer本身是可以接收事件的。

MetaData

// TODO

UTILITY NODES

Semantics

// TODO

MergeSemantics

// TODO

BlockSemantics

// TODO

ExcludeSemantics

// TODO

KeyedSubtree

// TODO

Builder

// TODO

StatefulBuilder

// TOD

你可能感兴趣的:(basic.dart)