Flutter學習筆記(24)--SingleChildScrollView滾動組件


如需轉載,請注明出處:Flutter學習筆記(24)--SingleChildScrollView滾動組件

在我們實際的項目開發中,經常會遇到頁面UI內容過多,導致手機一屏展示不完的情況出現,以Android為例,在Android中遇到這類情況的做法通常就是使用ScrollView將內容包裹起來,如果不做可滑動的處理,Android上的表現為頁面的部分內容無法展示,而在Flutter中,如果內容過多無法展示完全,屏幕的邊界會給我們一個OVERFLOWED的警告提示,在Flutter中我們通常使用SingleChildScrollView處理滑動,這里需要注意的是,通常SingleChildScrollView只應在期望的內容不會超過屏幕太多時使用,這是因為SingleChildScrollView不支持基於Sliver的延遲實例化模式,所以如果預計視口可能包含超出屏幕尺寸太多的內容時使用SingleChildScrollView將會導致性能差的問題,此時應該使用一些支持Sliver延遲加載的可滾動組件,如ListView。

基於Sliver的延遲構建模式:

通常可滾動組件的子組件可能會非常多,占用的總高度也會非常大,如果要一次性將子組件全部構建出將會導致性能差的問題出現,為此,Flutter中提出一個Sliver(中文為"薄片"的意思)概念,如果一個可滾動組件支持Sliver模型,那么該滾動組件可以將子組件分成好多個薄片(Sliver),只有當Sliver出現在視口時才會去構建它,這種模型也成為"基於Sliver的延遲構建模型"。可滾動組件中有很多都支持基於Sliver的延遲構建模型,如ListView、GridView,但是也有不支持該模型的,如SingleChildScrollView

 

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'SingleChildScrollView Demo',
      home: new Scaffold(
        appBar: AppBar(
          title: new Text('SingleChildScrollView Demo'),
        ),
        body: new Center(
          child: new Column(
            children: <Widget>[
              Container(
                width: 300.0,
                height: 200.0,
                color: Colors.blue,
              ),
              Container(
                width: 300.0,
                height: 200.0,
                color: Colors.yellow,
              ),
              Container(
                width: 300.0,
                height: 200.0,
                color: Colors.pink,
              ),
              Container(
                width: 300.0,
                height: 200.0,
                color: Colors.blue,
              ),
              Container(
                width: 300.0,
                height: 200.0,
                color: Colors.yellow,
              ),
              Container(
                width: 300.0,
                height: 200.0,
                color: Colors.pink,
              ),
              Container(
                width: 300.0,
                height: 200.0,
                color: Colors.blue,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

 

在Flutter實現頁面滑動需要用到SingleChildScrollView組件,SingleChildScrollView和Android中ScrollView類似,都是只能接收一個子組件,先看一下SingleChildScrollView的源碼:

const SingleChildScrollView({
  Key key,
  //滾動方向,默認是垂直方向
  this.scrollDirection = Axis.vertical,
  //是否按照閱讀方向相反的方向滑動
  this.reverse = false,
  //內容邊距
  this.padding,
  //是否使用widget樹中默認的PrimaryScrollController
  bool primary,
  //此屬性接受一個ScrollPhysics類型的對象,它決定可以滾動如何響應用戶操作,比如用戶滑動完抬起手指后,繼續執行動畫,或者滑動到邊界時,如何顯示。
  //默認情況下,Flutter會根據具體平台分別使用不同的ScrollPhysics對象,對應不同的顯示效果,如當滑動到邊界時,繼續拖動的話,在iOS上會出現彈性效果,
  //而在Android上會出現微光效果。如果你想在所有平台下使用同一種效果,可以顯示指定一個固定的ScrollPhysics。
  //Flutter SDK包含兩個ScrollPhysics的子類。1.ClampingScrollPhysics:Android下微光效果,2.BouncingScrollPhysics:iOS下彈性效果
  this.physics,
  //此屬性接收一個ScrollController對象,ScrollController的主要作用是控制滾動位置和監聽滾動事件。
  //默認情況下,Widget樹中會有一個默認的PrimaryScrollController,如果子樹中的可滾動組件沒有顯示的指定controller,並且primary屬性值為true時,可滾動組件會使用這個默認的ScrollController。
  //這種機制帶來的好處是父組件可以控制子樹中可滾動的滾動行為,例:scaffold正是使用這種機制在iOS中實現了點擊導航回到頂部的功能。
  this.controller,
  this.child,
})

Demo示例:

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'SingleChildScrollView Demo',
      home: new Scaffold(
        appBar: AppBar(
          title: new Text('SingleChildScrollView Demo'),
        ),
        body: new SingleChildScrollView(
          physics: BouncingScrollPhysics(),
          child: new Center(
            child: new Column(
              children: <Widget>[
                Container(
                  width: 300.0,
                  height: 200.0,
                  color: Colors.blue,
                ),
                Container(
                  width: 300.0,
                  height: 200.0,
                  color: Colors.yellow,
                ),
                Container(
                  width: 300.0,
                  height: 200.0,
                  color: Colors.pink,
                ),
                Container(
                  width: 300.0,
                  height: 200.0,
                  color: Colors.blue,
                ),
                Container(
                  width: 300.0,
                  height: 200.0,
                  color: Colors.yellow,
                ),
                Container(
                  width: 300.0,
                  height: 200.0,
                  color: Colors.pink,
                ),
                Container(
                  width: 300.0,
                  height: 200.0,
                  color: Colors.blue,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

效果截圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM