欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Flutter Widgets粘合劑CustomScrollView NestedScrollView滾動(dòng)控件

 更新時(shí)間:2022年11月09日 15:11:41   作者:風(fēng)雨_83  
這篇文章主要為大家介紹了Flutter Widgets粘合劑CustomScrollView NestedScrollView滾動(dòng)控件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

概述:

Flutter中常用的滑動(dòng)布局 ScrollViewSingleChildScrollView、NestedScrollView、CustomScrollView。

SingleChildScrollView 用來處理簡(jiǎn)單可滑動(dòng)的頁面布局視圖,如一般的數(shù)據(jù)詳情頁面,當(dāng)內(nèi)容足夠多時(shí),一屏顯示不下時(shí),就需要滑動(dòng)處理。

NestedScrollView 滑動(dòng)組件是用來處理復(fù)雜情況下的滑動(dòng)應(yīng)用場(chǎng)景,如向上滑動(dòng)視圖時(shí),要折疊隱藏一部分內(nèi)容,這時(shí)候就需要使用到 NestedScrollView 與 SliverAppBar 的結(jié)合使用。

CustomScrollView 用來處理更為復(fù)雜的布局結(jié)合 SliverAppBar,SliverList和SliverGrid SliverPadding SliverToBoxAdapter SliverPersistentHeader, SliverFillRemaining,SliverFillViewport等來使用。

如一個(gè)詳情頁面中 即需要 GridView 來實(shí)現(xiàn)二維宮格效果,也需要 ListView 列表效果,如下圖所示的圖片效果,當(dāng)使用 CustomScrollView 結(jié)合 SliverList 和SliverGrid 就可輕松實(shí)現(xiàn),當(dāng)然結(jié)合一下 SliverAppBar 也能實(shí)現(xiàn)折疊效果的頭部布局,所以說 CustomScrollView 很強(qiáng)大。

在實(shí)際應(yīng)用開發(fā)中,如果只是一個(gè)簡(jiǎn)單的適配頁面滑動(dòng),建議碼農(nóng)使用 SingleChildScrollView 就可以。

如圖:

CustomScrollView

CustomScrollView是使用Sliver組件創(chuàng)建自定義滾動(dòng)效果的滾動(dòng)組件,使用場(chǎng)景:

ListView和GridView相互嵌套場(chǎng)景,ListView嵌套GridView時(shí),需要給GridView指定高度,但我們希望高度隨內(nèi)容而變化(不指定),ListView和GridView作為整體滾動(dòng)效果。

一個(gè)頁面頂部是AppBar,然后是GridView,最后是ListView,這3個(gè)區(qū)域以整體來滾動(dòng),AppBar具有吸頂效果。

CustomScrollView就像一個(gè)粘合劑,將多個(gè)組件粘合在一起,具統(tǒng)一的滾動(dòng)效果。

Sliver系列組件有很多,比如SliverList、SliverGrid、SliverFixedExtentList、SliverPadding、SliverAppBar等。

相互嵌套場(chǎng)景

在實(shí)際業(yè)務(wù)場(chǎng)景中經(jīng)常見到這樣的布局,頂部是懸浮導(dǎo)航,接下來網(wǎng)格布局(GridView),然后是列表布局(ListView),滾動(dòng)的時(shí)候做為一個(gè)整體,此場(chǎng)景是無法使用GridView+ListView來實(shí)現(xiàn)的,而是需要使用CustomScrollView+SliverAppBar+SliverGrid+SliverList來實(shí)現(xiàn),

CustomScrollView buildCustomScrollView() {
    return CustomScrollView(
      ///反彈效果
      physics: BouncingScrollPhysics(),
      ///Sliver 家族的 Widget
      slivers: <Widget>[
        ///復(fù)雜的標(biāo)題
        buildSliverAppBar(),
        ///間距
        SliverPadding(
          padding: EdgeInsets.all(5),
        ),
        ///九宮格
        buildSliverGrid(),
        ///間距
        SliverPadding(
          padding: EdgeInsets.all(5),
        ),
        ///列表
        buildSliverFixedExtentList()
      ],
    );
  }

SliverAppBar 常用來實(shí)現(xiàn)復(fù)雜的可折疊效果的頭布局,代碼如下:

SliverAppBar buildSliverAppBar() {
    return SliverAppBar(
      title: Text("講解組合滑動(dòng)"),
    );
  }

CustomScrollView 中使用的九宮格你不能再去使用 GridView了,在Sliver家族中,有SliverGridView,當(dāng)然它與 GridView 的用法是一致的,代碼如下:

 SliverGrid buildSliverGrid() {
    return SliverGrid(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        ///九宮格的列數(shù)
        crossAxisCount: 3,
        ///子Widget 寬與高的比值
        childAspectRatio: 2.0,
        ///主方向的 兩個(gè) 子Widget 之間的間距
        mainAxisSpacing: 10,
        /// 次方向 子Widget 之間的間距
        crossAxisSpacing: 10,
      ),
      ///子Item構(gòu)建器
      delegate: new SliverChildBuilderDelegate(
            (BuildContext context, num index) {
          ///每一個(gè)子Item的樣式
          return Container(
            color: Colors.blue,
            child: Text("grid $index"),
          );
        },
        ///子Item的個(gè)數(shù)
        childCount: 10,
      ),
    );
  }

CustomScrollView 使用的列表你也不能使用 ListView了,需要使用SliverListView 或者是 SliverFixedExtentList,當(dāng)然在這里使用了 SliverFixedExtentList 代碼如下:

 SliverFixedExtentList buildSliverFixedExtentList() {
    return SliverFixedExtentList(
      ///子條目的高度
      itemExtent: 40,
      ///子條目布局構(gòu)建代理
      delegate: new SliverChildBuilderDelegate(
            (BuildContext context, num index) {
          ///子條目的布局樣式
          return Container(
            color: Colors.red,
            child: Text("list $index"),
            margin: EdgeInsets.only(bottom: 10),
          );
        },
        ///子條目的個(gè)數(shù)
        childCount: 40,
      ),
    );
  }

最終效果(上滑導(dǎo)航隱藏,下滑導(dǎo)航懸浮):

實(shí)際項(xiàng)目中頁面頂部是AppBar,然后是GridView,最后是ListView,這3個(gè)區(qū)域以整體來滾動(dòng),AppBar具有吸頂效果,此效果也是我們經(jīng)常遇到的,用法如下:

 CustomScrollView buildCustomScrollView1() {
    return CustomScrollView(
      slivers: <Widget>[
        SliverAppBar(
          pinned: true,
          expandedHeight: 230.0,
          flexibleSpace: FlexibleSpaceBar(
            title: Text('復(fù)仇者聯(lián)盟'),
            background: Image.network(
              'http://img.haote.com/upload/20180918/2018091815372344164.jpg',
              fit: BoxFit.fitHeight,
            ),
          ),
        ),
        SliverGrid.count(crossAxisCount: 4,children: List.generate(8, (index){
          return Container(
            color: Colors.primaries[index%Colors.primaries.length],
            alignment: Alignment.center,
            child: Text('$index',style: TextStyle(color: Colors.white,fontSize: 20),),
          );
        }).toList(),),
        SliverList(
          delegate: SliverChildBuilderDelegate((content, index) {
            return Container(
              height: 85,
              alignment: Alignment.center,
              color: Colors.primaries[index % Colors.primaries.length],
              child: Text('$index',style: TextStyle(color: Colors.white,fontSize: 20),),
            );
          }, childCount: 25),
        )
      ],
    );
  }

運(yùn)行效果:

通過scrollDirectionreverse參數(shù)控制其滾動(dòng)方向,用法如下:

CustomScrollView(
  scrollDirection: Axis.horizontal,
  reverse: true,
  ...
)

scrollDirection滾動(dòng)方向,分為垂直和水平方向。

reverse參數(shù)表示反轉(zhuǎn)滾動(dòng)方向,并不是垂直轉(zhuǎn)為水平,而是垂直方向滾動(dòng)時(shí),默認(rèn)向下滾動(dòng),reverse設(shè)置false,滾動(dòng)方向改為向上,同理水平滾動(dòng)改為水平向左。

設(shè)置scrollDirection:Axis.horizontal效果:

primary設(shè)置為true時(shí),不能設(shè)置controller,因?yàn)閜rimarytrue時(shí),controller使用PrimaryScrollController,這種機(jī)制帶來的好處是父組件可以控制子樹中可滾動(dòng)組件的滾動(dòng)行為,例如,Scaffold正是使用這種機(jī)制在iOS中實(shí)現(xiàn)了點(diǎn)擊導(dǎo)航欄回到頂部的功能。

controller為滾動(dòng)控制器,可以監(jiān)聽滾到的位置,設(shè)置滾動(dòng)的位置等,用法如下:

_scrollController = ScrollController();
//監(jiān)聽滾動(dòng)位置
    _scrollController.addListener((){
      print('${_scrollController.position}');
    });
    //滾動(dòng)到指定位置
    _scrollController.animateTo(20.0);
CustomScrollView(
  controller: _scrollController,
  ...
)

physics表示可滾動(dòng)組件的物理滾動(dòng)特性,系統(tǒng)提供的ScrollPhysics有:

AlwaysScrollableScrollPhysics:總是可以滑動(dòng)

NeverScrollableScrollPhysics:禁止?jié)L動(dòng)

BouncingScrollPhysics :內(nèi)容超過一屏 上拉有回彈效果

ClampingScrollPhysics :包裹內(nèi)容 不會(huì)有回彈

NestedScrollView

可以在其內(nèi)部嵌套其他滾動(dòng)視圖的組件,其滾動(dòng)位置是固有鏈接的。

在普通的ScrollView中, 如果有一個(gè)Sliver組件容納了一個(gè)TabBarView,它沿相反的方向滾動(dòng)(例如,允許用戶在標(biāo)簽所代表的頁面之間水平滑動(dòng),而列表則垂直滾動(dòng)),則該TabBarView內(nèi)部的任何列表都不會(huì)相互作用 與外部ScrollView。例如,瀏覽內(nèi)部列表以滾動(dòng)到頂部不會(huì)導(dǎo)致外部ScrollView中的SliverAppBar折疊以展開。

滾動(dòng)隱藏AppBar

代碼如下:

_buildNestedScrollView(){
    return NestedScrollView(
        headerSliverBuilder: (BuildContext context,bool innerBoxIsScrolled){
          return [
            SliverAppBar(title: Text('導(dǎo)航測(cè)試'),)
          ];
        },
        body: MediaQuery.removePadding(
          removeTop: true,
            context: context,
            child: ListView.builder(itemBuilder: (BuildContext context,int index){
          return Container(
            height: 120,
            color: Colors.primaries[index%Colors.primaries.length],
            alignment: Alignment.center,
            child: Text(
              '組合ListView $index',
              style: TextStyle(color: Colors.white,fontSize: 30),
            ),
          );
        }))
    );
  }

運(yùn)行效果:

注意, 如不不加MediaQuery.removePadding移除頂部間距,有個(gè)小bug。ListView和Appbar之間存在一個(gè)很大的間距,這個(gè)時(shí)候就需要MediaQuery去移除ListView的padding。

 SliverAppBar展開折疊

_buildNestedScrollView1(){
    return NestedScrollView(
        headerSliverBuilder: (BuildContext context,bool innerBoxIsScrolled){
          return [
            SliverAppBar(
              expandedHeight: 230,
              pinned: true,
              flexibleSpace: FlexibleSpaceBar(
                title: Text('復(fù)仇者聯(lián)盟'),
                background: Image.network(
                  'http://img.haote.com/upload/20180918/2018091815372344164.jpg',
                  fit: BoxFit.fitHeight,
                ),
              ),
            )
          ];
        },
        body: ListView.builder(itemBuilder: (BuildContext context,int index){
          print('create $index');
          return Container(
            height: 100,
            color: Colors.primaries[index%Colors.primaries.length],
            alignment: Alignment.center,
            child: Text('$index 測(cè)試ListView',style: TextStyle(fontSize: 30),
            ),
          );
        }));
  }

運(yùn)行效果(白色間距可以增加removepadding去除):

 與TabBar配合使用

用法如下:

_buildNestedScrollViewTabBar() {
    return NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return [
            const SliverAppBar(
              expandedHeight: 230,
              pinned: true,
              flexibleSpace: Padding(
                padding: EdgeInsets.symmetric(vertical: 8),
                child: WyPageView(),
              ),
            ),
            SliverPersistentHeader(
              pinned: true,
              delegate: StickyTabBarDelegate(
                TabBar(
                  labelColor: Colors.black,
                  controller: this._tabController,
                  tabs: [
                    const Tab(text: '資訊',),
                    const Tab(text: '技術(shù)',),
                  ],
                ),
              ),
            )
          ];
        },
        body: TabBarView(
          controller: this._tabController,
            children: [
              RefreshIndicator(
                  child: _buildTabNewsList('----資訊類----'),
                  onRefresh: _handelRefresh,
              ),
              _buildTabNewsList('----技術(shù)類----'),
            ])
    );
  }
  //Refresh異步刷新方法
   Future<Null >_handelRefresh()async{
    print('加載數(shù)據(jù)');
    return null;
   }
   //構(gòu)建newstlist列表
  _buildTabNewsList(String name) {
    return ListView.separated(itemBuilder: (context, int index) {
      return Column(
        children: [
          Text('$name $index 通過scrollDirection和reverse參數(shù)控制其滾動(dòng)方向,用法如下:',
            style: TextStyle(fontSize: 18),),
          Text(
            '作者 csdn賬號(hào) ', style: TextStyle(fontSize: 12, color: Colors.grey),),
        ],
      );
    },
        separatorBuilder: (context, index) => Divider(),
        itemCount: 50);
  }
}
//StickyTabBarDelegate 代碼如下:
class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {
  final TabBar child;
  StickyTabBarDelegate(this.child);
  @override
  Widget build(BuildContext context, double shrinkOffset,
      bool overlapsContent) {
    // TODO: implement build
    return Container(
      color: Theme
          .of(context)
          .backgroundColor,
      child: this.child,
    );
  }
  @override
  // TODO: implement maxExtent
  double get maxExtent => this.child.preferredSize.height;
  @override
  // TODO: implement minExtent
  double get minExtent => this.child.preferredSize.height;
  @override
  bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
    // TODO: implement shouldRebuild
    throw true;
  }
}

運(yùn)行效果:

總結(jié):

本篇主要介紹了CustomScrollViewNestedScrollView,CustomScrollView的自定義靈活性更大,所有子組件都用Sliver家族組件,一般需求用NestedScrollView即可。

以上就是Flutter Widgets粘合劑CustomScrollView NestedScrollView滾動(dòng)控件的詳細(xì)內(nèi)容,更多關(guān)于Flutter Widgets滾動(dòng)控件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論