IT达摩院

畅想中

Flutter Scrolling Widgets由*GridView* ,ListView ,NestedScrollView ,*SingleChildScrollView*构成。

  • GridView 网格视图是由一些横向和纵向排列的具有可重复的模式的单元格列表构成;

    构造函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    使用案例:

    GridView.count(
    primary: false,
    padding: const EdgeInsets.all(20.0),
    crossAxisSpacing: 10.0,
    crossAxisCount: 2,
    children: <Widget>[
    const Text('He\'d have you all unravel at the'),
    const Text('Heed not the rabble'),
    const Text('Sound of screams but the'),
    const Text('Who scream'),
    const Text('Revolution is coming...'),
    const Text('Revolution, they...'),
    ],
    )

    CustomScrollView(
    primary: false,
    slivers: <Widget>[
    SliverPadding(
    padding: const EdgeInsets.all(20.0),
    sliver: SliverGrid.count(
    crossAxisSpacing: 10.0,
    crossAxisCount: 2,
    children: <Widget>[
    const Text('He\'d have you all unravel at the'),
    const Text('Heed not the rabble'),
    const Text('Sound of screams but the'),
    const Text('Who scream'),
    const Text('Revolution is coming...'),
    const Text('Revolution, they...'),
    ],
    ),
    ),
    ],
    )
  • ListView 列表视图是一个可滚动的线性的Widget,它将其子Widget滚动方向一个一个地按排列;

    构造函数:

    1
    2
    3
    4
    5
    6
    7
    ListView.builder(
    padding: EdgeInsets.all(8.0),
    itemExtent: 20.0,
    itemBuilder: (BuildContext context, int index) {
    return Text('entry $index');
    },
    )
  • NestedScrollView 嵌套滚动视图,既视图的子视图仍可以是嵌套视图;

    构造函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    DefaultTabController(
    length: _tabs.length, // This is the number of tabs.
    child: NestedScrollView(
    headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
    // These are the slivers that show up in the "outer" scroll view.
    return <Widget>[
    SliverOverlapAbsorber(
    // This widget takes the overlapping behavior of the SliverAppBar,
    // and redirects it to the SliverOverlapInjector below. If it is
    // missing, then it is possible for the nested "inner" scroll view
    // below to end up under the SliverAppBar even when the inner
    // scroll view thinks it has not been scrolled.
    // This is not necessary if the "headerSliverBuilder" only builds
    // widgets that do not overlap the next sliver.
    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
    child: SliverAppBar(
    title: const Text('Books'), // This is the title in the app bar.
    pinned: true,
    expandedHeight: 150.0,
    // The "forceElevated" property causes the SliverAppBar to show
    // a shadow. The "innerBoxIsScrolled" parameter is true when the
    // inner scroll view is scrolled beyond its "zero" point, i.e.
    // when it appears to be scrolled below the SliverAppBar.
    // Without this, there are cases where the shadow would appear
    // or not appear inappropriately, because the SliverAppBar is
    // not actually aware of the precise position of the inner
    // scroll views.
    forceElevated: innerBoxIsScrolled,
    bottom: TabBar(
    // These are the widgets to put in each tab in the tab bar.
    tabs: _tabs.map((String name) => Tab(text: name)).toList(),
    ),
    ),
    ),
    ];
    },
    body: TabBarView(
    // These are the contents of the tab views, below the tabs.
    children: _tabs.map((String name) {
    return SafeArea(
    top: false,
    bottom: false,
    child: Builder(
    // This Builder is needed to provide a BuildContext that is "inside"
    // the NestedScrollView, so that sliverOverlapAbsorberHandleFor() can
    // find the NestedScrollView.
    builder: (BuildContext context) {
    return CustomScrollView(
    // The "controller" and "primary" members should be left
    // unset, so that the NestedScrollView can control this
    // inner scroll view.
    // If the "controller" property is set, then this scroll
    // view will not be associated with the NestedScrollView.
    // The PageStorageKey should be unique to this ScrollView;
    // it allows the list to remember its scroll position when
    // the tab view is not on the screen.
    key: PageStorageKey<String>(name),
    slivers: <Widget>[
    SliverOverlapInjector(
    // This is the flip side of the SliverOverlapAbsorber above.
    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
    ),
    SliverPadding(
    padding: const EdgeInsets.all(8.0),
    // In this example, the inner scroll view has
    // fixed-height list items, hence the use of
    // SliverFixedExtentList. However, one could use any
    // sliver widget here, e.g. SliverList or SliverGrid.
    sliver: SliverFixedExtentList(
    // The items in this example are fixed to 48 pixels
    // high. This matches the Material Design spec for
    // ListTile widgets.
    itemExtent: 48.0,
    delegate: SliverChildBuilderDelegate(
    (BuildContext context, int index) {
    // This builder is called for each child.
    // In this example, we just number each list item.
    return ListTile(
    title: Text('Item $index'),
    );
    },
    // The childCount of the SliverChildBuilderDelegate
    // specifies how many children this inner list
    // has. In this example, each tab has a list of
    // exactly 30 items, but this is arbitrary.
    childCount: 30,
    ),
    ),
    ),
    ],
    );
    },
    ),
    );
    }).toList(),
    ),
    ),
    )
  • SingleChildScrollView 一个可使单Widget可滚动的盒子;

    构造函数:

    1

Flutter Styling Widgets由*Padding* ,Theme ,MediaQuery 构成。

  • Padding 创建一个Widget来约束子元素与边界的距离;

    构造函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      const Padding({
    Key key,
    @required this.padding,
    Widget child,
    }) : assert(padding != null),
    super(key: key, child: child);

    使用案例:

    Padding(
    padding: EdgeInsets.all(100),
    child: Text("你好!!!"),
    )
  • ThemeData 创建合适的方案数据,如明暗度,大小等;

  • MediaQuery 构建一棵子树来查询给定的媒体数据,Flutter由一系列的Widgets构成,要得到和计算出各个Widget的大小,需要一棵关系树来维护相关媒体数据;

Flutter Text Widgets由*Text* ,RichText ,DefaultTextStyle 构成。

  • Text由单一的样式来显示文本;

    构造函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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,
    }) : assert(data != null),
    textSpan = null,
    super(key: key);
  • RichText由多种不同的样式来显示文本;

    构造函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    const RichText({
    Key key,
    @required this.text,
    this.textAlign = TextAlign.start,
    this.textDirection,
    this.softWrap = true,
    this.overflow = TextOverflow.clip,
    this.textScaleFactor = 1.0,
    this.maxLines,
    this.locale,
    this.strutStyle,
    }) : assert(text != null),
    assert(textAlign != null),
    assert(softWrap != null),
    assert(overflow != null),
    assert(textScaleFactor != null),
    assert(maxLines == null || maxLines > 0),
    super(key: key);
  • DefaultTextStyle对于没有明确样式的子文本元素设置默认的文本样式;

    构造函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    const DefaultTextStyle({
    Key key,
    @required this.style,
    this.textAlign,
    this.softWrap = true,
    this.overflow = TextOverflow.clip,
    this.maxLines,
    @required Widget child,
    }) : assert(style != null),
    assert(softWrap != null),
    assert(overflow != null),
    assert(maxLines == null || maxLines > 0),
    assert(child != null),
    super(key: key, child: child);
0%