Introduction to Old Meng Yesterday, Version 1.17 of Flutter was released. The new version is mainly designed to optimize performance and fix bugs. Some people feel that this version is not exciting, but it also shows that Flutter is better for mobile applications. Some people upgrade and the project doesn’t work. The component introduced today is NestedScrollView, which is used by most App home pages.

Scroll views that can be nested within other scroll views, and whose scroll positions are inherently linked.

In a normal ScrollView, if you have a Sliver component that holds a TabBarView that scrolls in the opposite direction (for example, allowing the user to slide horizontally between pages represented by a label and vertically scroll a list), Then any list inside the TabBarView will not interact with the external ScrollView. For example, browsing the internal list to scroll to the top does not cause the SliverAppBar in the external ScrollView to collapse to expand.

Scroll to hide the AppBar

For example, implement the following scenario, while the list is scrolling, hide the AppBar, as follows:

NestedScrollView(
  headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
    return <Widget>[SliverAppBar(
      title: Text('the old meng'), a)]; }, body: ListView.builder(itemBuilder: (BuildContext context,int index){
    return Container(
      height: 80,
      color: Colors.primaries[index % Colors.primaries.length],
      alignment: Alignment.center,
      child: Text(
        '$index',
        style: TextStyle(color: Colors.white, fontSize: 20),),); },itemCount:20,),)Copy the code

The effect is as follows:

SliverAppBar expands and collapses

Usage:

NestedScrollView(
  headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
    return <Widget>[SliverAppBar(
      expandedHeight: 230.0,
      pinned: true,
      flexibleSpace: FlexibleSpaceBar(
        title: Text('The Avengers'),
        background: Image.network(
          'http://img.haote.com/upload/20180918/2018091815372344164.jpg',
          fit: BoxFit.fitHeight,
        ),
      ),
    )];
  },
  body: ListView.builder(itemBuilder: (BuildContext context,int index){
    return Container(
      height: 80,
      color: Colors.primaries[index % Colors.primaries.length],
      alignment: Alignment.center,
      child: Text(
        '$index',
        style: TextStyle(color: Colors.white, fontSize: 20),),); },itemCount:20,),)Copy the code

The effect is as follows:

Use with TabBar

Usage:

NestedScrollView(
  headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
    return <Widget>[
      SliverAppBar(
        expandedHeight: 230.0,
        pinned: true,
        flexibleSpace: Padding(
          padding: EdgeInsets.symmetric(vertical: 8),
          child: PageView(),
        ),
      ),
      SliverPersistentHeader(
        pinned: true,
        delegate: StickyTabBarDelegate(
          child: TabBar(
            labelColor: Colors.black,
            controller: this._tabController,
            tabs: <Widget>[
              Tab(text: 'information'),
              Tab(text: 'technology'[, [, [, [, [, [ }, body: TabBarView( controller:this._tabController,
    children: <Widget>[
      RefreshIndicator(
        onRefresh: (){
          print(('onRefresh'));
        },
        child: _buildTabNewsList(_newsKey, _newsList),
      ),

      _buildTabNewsList(_technologyKey, _technologyList),
    ],
  ),
)
Copy the code

The StickyTabBarDelegate code looks like this:

class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {
  final TabBar child;

  StickyTabBarDelegate({@required this.child});

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      color: Theme.of(context).backgroundColor,
      child: this.child,
    );
  }

  @override
  double get maxExtent => this.child.preferredSize.height;

  @override
  double get minExtent => this.child.preferredSize.height;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    return true; }}Copy the code

The effect is as follows:

Other attributes

The scrollDirection and reverse parameters are used to control the scrolling direction as follows:

NestedScrollView(
  scrollDirection: Axis.horizontal,
  reverse: true,...).Copy the code

ScrollDirection Indicates the rolling direction, which can be vertical or horizontal.

The reverse parameter indicates that the scrolling direction is reversed, not from vertical to horizontal. Instead, when scrolling vertically, the default scrolling direction is down. The reverse parameter is set to false, and the scrolling direction is changed to up.

Controller is the scroll controller, which can monitor the position to be rolled to, set the scroll position, etc.

_scrollController = ScrollController();

// Listen for the scroll position
    _scrollController.addListener((){
      print('${_scrollController.position}');
    });
    // Scroll to the specified position
    _scrollController.animateTo(20.0);

CustomScrollView(
	controller: _scrollController,
	...
) 
Copy the code

Physics Indicates the physical rolling properties of a scrollable component. For details, see ScrollPhysics

communication

Old Meng Flutter blog address (nearly 200 controls usage) : laomengit.com