Flutter組件學習(20)可滾動組件以及ScrollController監聽

介紹

ViewPort視口

在很多佈局系統中都有ViewPort的概念,在Flutter中,術語ViewPort(視口),如無特別說明,則是指一個Widget的實際顯示區域。例如,一個ListView的顯示區域高度是800像素,雖然其列表項總高度可能遠遠超過800像素,但是其ViewPort仍然是800像素。

Scrollbar

Scrollbar是一個Material風格的滾動指示器(滾動條),如果要給可滾動組件添加滾動條,只需將Scrollbar作爲可滾動組件的任意一個父級組件即可

CupertinoScrollbar

CupertinoScrollbar是iOS風格的滾動條,如果使用的是Scrollbar,那麼在iOS平臺它會自動切換爲CupertinoScrollbar

基於Sliver的延遲構建

通常可滾動組件的子組件可能會非常多、佔用的總高度也會非常大;如果要一次性將子組件全部構建出將會非常昂貴!爲此,Flutter中提出一個Sliver(中文爲“薄片”的意思)概念,如果一個可滾動組件支持Sliver模型,那麼該滾動可以將子組件分成好多個“薄片”(Sliver),只有當Sliver出現在視口中時纔會去構建它,這種模型也稱爲“基於Sliver的延遲構建模型”。可滾動組件中有很多都支持基於Sliver的延遲構建模型,如ListViewGridView,但是也有不支持該模型的,如SingleChildScrollView

ScrollController

ScrollController間接繼承自Listenable,我們可以根據ScrollController來監聽滾動事件,

可以用ScrollController來控制可滾動組件的滾動位置

offset 可滾動組件 當前的滾動位置

jumpTo

animateTo

跳轉到指定的位置,

它們不同之處在於,後者在跳轉時會執行一個動畫,而前者不會

dispose 爲了避免內存泄露,需要調用 controller.dispose

demo

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyAppText());
}

class MyAppText extends StatefulWidget {

  @override
  ListViewClass createState() {
    return ListViewClass();
  }
}

class ListViewClass extends State {

  ScrollController _controller=new ScrollController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controller.addListener((){
      print(_controller.offset);
    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    List<String> list = new List();
    for (int i = 0; i < 100; i++) {
      list.add("我和我的祖國$i");
    }

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.red,
          title: Text('Controller練習'),
          textTheme:
              TextTheme(title: TextStyle(fontSize: 18, color: Colors.yellow)),
        ),
        body: Scrollbar(
          child: ListView.separated(
            controller: _controller,
            separatorBuilder: (BuildContext context, int dex) {
              return Divider(
                color: Colors.blue,
                height: 1,
              );
            },
            itemCount: list.length,
            itemBuilder: (BuildContext context, int dex) {
              return ListTile(
                title: Text('${list[dex]}'),
              );
            },
          ),
        ),

        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.arrow_upward),
          onPressed: (){
//            _controller.jumpTo(0);//點擊按鈕回調頂部
            _controller.animateTo(0,
                duration: Duration(
                  milliseconds: 300
                ),
                curve: Curves.ease);
          },
        ),
      ),
    );
  }
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章