天天看點

flutter listview 滾動到底部_【Flutter】NestedScrollView可滾動元件以及和其他元件搭配使用...

NestedScrollView元件

可以在其内部嵌套其他滾動視圖的滾動視圖,其滾動位置是固有連結的。

在普通的[ScrollView]中,如果有一個Sliver元件容納了一個[TabBarView],它沿相反的方向滾動(例如,允許使用者在标簽所代表的頁面之間水準滑動,而清單則垂直滾動),則該[TabBarView]内部的任何清單都不會互相作用與外部[ScrollView]。

如:浏覽内部清單以滾動到頂部不會導緻外部[ScrollView]中的[SliverAppBar]折疊以展開。

SliverPersistentHeader元件

SliverPersistentHeader控件當滾動到邊緣時根據滾動的距離縮小高度,有點類似 SliverAppBar 的背景效果。

SliverPersistentHeader的delegate屬性

需要自定義,build傳回顯示的内容,maxExtent和minExtent表示最大和最小值,滾動的時候高度在這個範圍内變化。shouldRebuild表示是否需要更新,如果内容需要變化需要設定為true。

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;

  @overridebool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    return true;
  }
}
           

常用屬性:

  • floating 設定為true時,向下滑動時,即使目前CustomScrollView不在頂部,SliverAppBar也會跟着一起向下出現
  • pinned:設定懸停在頂部,設定為true時,當SliverAppBar内容滑出螢幕時,将始終渲染一個固定在頂部的收起狀态

FlexibleSpaceBar元件

AppBar的一部分,它可以擴充,折疊,延伸,最常用于SliverAppBar.flexibleSpace字段。

FlexibleSpaceBar中的stretchModes屬性:

參數控制拉伸區域的滾動特性:

  • StretchMode.zoomBackground- >背景小部件将展開以填充額外的空間。 
  • StretchMode.blurBackground- >使用[ImageFilter.blur]效果,背景将模糊。 
  • StretchMode.fadeTitle- >随着使用者過度滾動,标題将消失。

使用stretchModes屬性需要開始stretch模式,可設定單個或者多個:

SliverAppBar(
  pinned: true,
  expandedHeight: 200.0,
  stretch: true,
  flexibleSpace: FlexibleSpaceBar(
    stretchModes: [StretchMode.zoomBackground],
    ...
)
           

可以通過stretchTriggerOffset 和onStretchTrigger監聽拉伸事件,用法如下:

SliverAppBar(
  stretch: true,
  stretchTriggerOffset: 100,
  onStretchTrigger: (){
    print('onStretchTrigger');
  },
  ...
)
           

注意:這個屬性是在SliverAppBar中設定,但拉伸超過100時,将會回調onStretchTrigger函數。

示例一,隐藏标題欄

import 'package:flutter/material.dart';

class NestedScrollViewDemo1 extends StatefulWidget {
  @override
  StatecreateState() {
    return NestedScrollViewDemo1State();
  }
}

class NestedScrollViewDemo1State extends State<NestedScrollViewDemo1> {
  @override
  Widget build(BuildContext context) {
    return NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return [
          SliverAppBar(
            title: Text('碼上加油站'),
          )
        ];
      },
      body: SingleChildScrollView(
        reverse: false,
        child: Container(
          color: Colors.grey,
          height: 1500,
          alignment: Alignment.center,
          width: double.infinity,
          child: Text("碼\n上\n加\n油\n站\n,\n一\n起\n來\n加\n油\n吧\n,\n學\n習\nFLutter\n!",
            style: TextStyle(fontSize: 28),
          ),
        ),
      ),
    );
  }
}
           

效果:

flutter listview 滾動到底部_【Flutter】NestedScrollView可滾動元件以及和其他元件搭配使用...

示例二 和SliverAppBar一起使用

import 'package:flutter/material.dart';

class NestedScrollViewDemo2 extends StatefulWidget {
  @override
  StatecreateState() {
    return NestedScrollViewDemo2State();
  }
}

class NestedScrollViewDemo2State extends State<NestedScrollViewDemo2> {
  @override
  Widget build(BuildContext context) {
    return NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return [SliverAppBar(
          expandedHeight: 230.0,
          pinned: true,
          flexibleSpace: FlexibleSpaceBar(
            centerTitle: true,
            title: Text('戰狼'),
            background: Image.network('https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1396864856,3131267503&fm=26&gp=0.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,),
    )
    ;
  }
}
           

效果:

flutter listview 滾動到底部_【Flutter】NestedScrollView可滾動元件以及和其他元件搭配使用...

示例三-與TabBar和SliverPersistentHeader搭配使用

import 'dart:ui';

import 'package:flutter/material.dart';

class NestedScrollViewDemo3 extends StatefulWidget {
  @override
  StatecreateState() {
    return NestedScrollViewDemo3State();
  }
}

class NestedScrollViewDemo3State extends State<NestedScrollViewDemo3> {
  TabController _controller;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controller = TabController(
      length: 2,
      vsync: ScrollableState(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return [
            SliverAppBar(
              title: Text("碼上加油站"),
              expandedHeight: 230.0,
              pinned: true,
              flexibleSpace: Padding(
                padding: EdgeInsets.symmetric(vertical: 1),
                child: PageView(
                  children: [
                    Container(
                      height: 230,
                      color: Colors.redAccent,
                    ),
                    Container(
                      height: 230,
                      color: Colors.orange,
                    ),
                    Container(
                      height: 230,
                      color: Colors.lightBlue,
                    )
                  ],
                ),
              ),
            ),
            SliverPersistentHeader(
              pinned: true,
              delegate: StickyTabBarDelegate(
                child: TabBar(
                  labelStyle: TextStyle(
                      color: Colors.white,
                      fontSize: 14.0,
                      fontWeight: FontWeight.w600),
                  unselectedLabelStyle: TextStyle(
                      color: Colors.white,
                      fontSize: 14.0,
                      fontWeight: FontWeight.w600),
                  unselectedLabelColor: Colors.white60,
                  labelColor: Colors.white,
                  controller: _controller,
                  tabs: [
                    Tab(text: "熱門"),
                    Tab(text: "推薦"),
                  ],
                ),
              ),
            ),
          ];
        },
        body: TabBarView(
          controller: _controller,
          children: [
            ListView(
              children: [
                ListTile(title: Text("第一個tab")),
                ListTile(title: Text("第一個tab")),
                ListTile(title: Text("第一個tab"))
              ],
            ),
            ListView(
              children: [
                ListTile(title: Text("第二個tab")),
                ListTile(title: Text("第二個tab")),
                ListTile(title: Text("第二個tab"))
              ],
            )
          ],
        ),
      ),
    );
  }
}class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {final TabBar child;
  StickyTabBarDelegate({@required this.child});@overrideWidget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {return Container(
      color: Theme.of(context).backgroundColor,
      child: this.child,
    );
  }@overridedouble get maxExtent => this.child.preferredSize.height;@overridedouble get minExtent => this.child.preferredSize.height;@overridebool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {return true;
  }
}
           

說明:delegate需要實作SliverPersistentHeaderDelegate 重寫其中的build方法實作子類容器, shouldRebuild方法中根據使用者自定義重繪條件傳回布爾值。

效果:

flutter listview 滾動到底部_【Flutter】NestedScrollView可滾動元件以及和其他元件搭配使用...

  碼上加油站

  一起來加油

長按掃碼關注

flutter listview 滾動到底部_【Flutter】NestedScrollView可滾動元件以及和其他元件搭配使用...

記得點個 贊 和 在看 哦!