<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
列表 ListView 是應用中最為常見的元件,而列表往往也會承載很多元素,當元素多,尤其是那種圖片檔案比較大的場合,就可能會導致列表卡頓,嚴重的時候可能導致應用崩潰。本篇來介紹如何優化列表。
當你的列表元素是動態增長的時候(比如上拉載入更多),請不要直接用children
的方式,一直往children
的陣列增加元件,那樣會很糟糕。
//糟糕的用法 ListView( children: [ item1, item2, item3, ... ], ) //正確的用法 ListView.builder( itemBuilder: (context, index) => ListItem(), itemCount: itemCount, )
對於 ListView.builder 是按需構建列表元素,也就是隻有那些可見的元素才會呼叫itemBuilder 構建元素,這樣對於大列表而言效能開銷自然會小很多。
Creates a scrollable, linear array of widgets that are created on demand. This constructor is appropriate for list views with a large (or infinite) number of children because the builder is called only for those children that are actually visible.
這兩個屬性都是為了優化捲動過程中的使用者體驗的。addAutomaticKeepAlives
特性預設是 true
,意思是在列表元素不可見後可以保持元素的狀態,從而在再次出現在螢幕的時候能夠快速構建。這其實是一個拿空間換時間的方法,會造成一定程度的記憶體開銷。可以設定為 false
關閉這一特性。缺點是滑動過快的時候可能會出現短暫的白屏(實際會很少發生)。
addRepaintBoundaries
是將列表元素使用一個重繪邊界(Repaint Boundary)包裹,從而使得捲動的時候可以避免重繪。而如果列表很容易繪製(列表元素佈局比較簡單的情況下)的時候,可以關閉這個特性來提高捲動的流暢度。
addAutomaticKeepAlives: false, addRepaintBoundaries: false,
使用 const
相當於將元素快取起來實現共用,若列表元素某些部分一直保持不變,那麼可以使用 const
修飾。
return Padding( child: Row( children: [ const ListImage(), const SizedBox( width: 5.0, ), Text('第$index 個元素'), ], ), padding: EdgeInsets.all(10.0), );
對於很多列表,我們在捲動方向上的尺寸是提前可以根據 UI設計稿知道的,如果能夠知道的話,那麼使用 itemExtent
屬性制定列表元素在捲動方向的尺寸,可以提升效能。這是因為,如果不指定的話,在捲動過程中,會需要推算每個元素在捲動方向的尺寸從而消耗計算資源。
itemExtent: 120,
下面是一開始未改造的列表,嗯,可以認為是垃圾程式碼。
class LargeListView extends StatefulWidget { const LargeListView({Key? key}) : super(key: key); @override _LargeListViewState createState() => _LargeListViewState(); } class _LargeListViewState extends State<LargeListView> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('大列表'), brightness: Brightness.dark, ), body: ListView( children: List.generate( 1000, (index) => Padding( padding: EdgeInsets.all(10.0), child: Row( children: [ Image.network( 'https://s3.ap-northeast-1.wasabisys.com/img.it145.com/202205/7869eac08a7d4177b600dc7d64998204~tplv-k3u1fbpfcp-watermarkykgv2u5h0hi.jpg', width: 200, ), const SizedBox( width: 5.0, ), Text('第$index 個元素'), ], ), ), ), ), ); } }
當然,實際不會是用 List.generate
來生成列表元素,但是也不要用一個 List<Widget>
列表物件一直往裡面加列表元素,然後把這個列表作為 ListView
的 children
!改造後的程式碼如下所示,因為將列表元素拆分得更細,程式碼量是多一些,但是效能上會好很多。
import 'package:flutter/material.dart'; class LargeListView extends StatefulWidget { const LargeListView({Key? key}) : super(key: key); @override _LargeListViewState createState() => _LargeListViewState(); } class _LargeListViewState extends State<LargeListView> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('大列表'), brightness: Brightness.dark, ), body: ListView.builder( itemBuilder: (context, index) => ListItem( index: index, ), itemCount: 1000, addAutomaticKeepAlives: false, addRepaintBoundaries: false, itemExtent: 120.0, ), ); } } class ListItem extends StatelessWidget { final int index; ListItem({Key? key, required this.index}) : super(key: key); @override Widget build(BuildContext context) { return Padding( child: Row( children: [ const ListImage(), const SizedBox( width: 5.0, ), Text('第$index 個元素'), ], ), padding: EdgeInsets.all(10.0), ); } } class ListImage extends StatelessWidget { const ListImage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Image.network( 'https://s3.ap-northeast-1.wasabisys.com/img.it145.com/202205/7869eac08a7d4177b600dc7d64998204~tplv-k3u1fbpfcp-watermarkykgv2u5h0hi.jpg', width: 200, ); } }
本篇介紹了 Flutter ListView
的4個優化要點,非常實用哦!實際上,這些要點都可以從官網的檔案裡找出對應的說明。因此,如果遇到了效能問題,除了搜尋引擎外,也建議多看看官方的檔案。另外一個,對於列表圖片,有時候也需要前後端配合,比如目前的手機都是號稱1億畫素的,如果上傳的時候直接上傳原圖,那麼載入如此大的圖片肯定是非常消耗資源的。對於這種情況,建議是生成列表縮圖(可能需要針對不同螢幕尺寸生成不同的縮圖)。
以上就是Android ListView列表優化的方法詳解的詳細內容,更多關於Android ListView列表優化的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45