您好,登錄后才能下訂單哦!
這篇文章主要講解了“Android ListView列表怎么優(yōu)化”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Android ListView列表怎么優(yōu)化”吧!
當(dāng)你的列表元素是動(dòng)態(tài)增長(zhǎng)的時(shí)候(比如上拉加載更多),請(qǐng)不要直接用children
的方式,一直往children
的數(shù)組增加組件,那樣會(huì)很糟糕。
//糟糕的用法 ListView( children: [ item1, item2, item3, ... ], ) //正確的用法 ListView.builder( itemBuilder: (context, index) => ListItem(), itemCount: itemCount, )
對(duì)于 ListView.builder 是按需構(gòu)建列表元素,也就是只有那些可見的元素才會(huì)調(diào)用itemBuilder 構(gòu)建元素,這樣對(duì)于大列表而言性能開銷自然會(huì)小很多。
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.
這兩個(gè)屬性都是為了優(yōu)化滾動(dòng)過程中的用戶體驗(yàn)的。addAutomaticKeepAlives
特性默認(rèn)是 true
,意思是在列表元素不可見后可以保持元素的狀態(tài),從而在再次出現(xiàn)在屏幕的時(shí)候能夠快速構(gòu)建。這其實(shí)是一個(gè)拿空間換時(shí)間的方法,會(huì)造成一定程度的內(nèi)存開銷??梢栽O(shè)置為 false
關(guān)閉這一特性。缺點(diǎn)是滑動(dòng)過快的時(shí)候可能會(huì)出現(xiàn)短暫的白屏(實(shí)際會(huì)很少發(fā)生)。
addRepaintBoundaries
是將列表元素使用一個(gè)重繪邊界(Repaint Boundary)包裹,從而使得滾動(dòng)的時(shí)候可以避免重繪。而如果列表很容易繪制(列表元素布局比較簡(jiǎn)單的情況下)的時(shí)候,可以關(guān)閉這個(gè)特性來提高滾動(dòng)的流暢度。
addAutomaticKeepAlives: false, addRepaintBoundaries: false,
使用 const
相當(dāng)于將元素緩存起來實(shí)現(xiàn)共用,若列表元素某些部分一直保持不變,那么可以使用 const
修飾。
return Padding( child: Row( children: [ const ListImage(), const SizedBox( width: 5.0, ), Text('第$index 個(gè)元素'), ], ), padding: EdgeInsets.all(10.0), );
對(duì)于很多列表,我們?cè)跐L動(dòng)方向上的尺寸是提前可以根據(jù) UI設(shè)計(jì)稿知道的,如果能夠知道的話,那么使用 itemExtent
屬性制定列表元素在滾動(dòng)方向的尺寸,可以提升性能。這是因?yàn)?,如果不指定的話,在滾動(dòng)過程中,會(huì)需要推算每個(gè)元素在滾動(dòng)方向的尺寸從而消耗計(jì)算資源。
itemExtent: 120,
下面是一開始未改造的列表,嗯,可以認(rèn)為是垃圾代碼。
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://cache.yisu.com/upload/information/20220517/112/2097.jpg', width: 200, ), const SizedBox( width: 5.0, ), Text('第$index 個(gè)元素'), ], ), ), ), ), ); } }
當(dāng)然,實(shí)際不會(huì)是用 List.generate
來生成列表元素,但是也不要用一個(gè) List<Widget>
列表對(duì)象一直往里面加列表元素,然后把這個(gè)列表作為 ListView
的 children
!改造后的代碼如下所示,因?yàn)閷⒘斜碓夭鸱值酶?xì),代碼量是多一些,但是性能上會(huì)好很多。
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 個(gè)元素'), ], ), 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://cache.yisu.com/upload/information/20220517/112/2097.jpg', width: 200, ); } }
感謝各位的閱讀,以上就是“Android ListView列表怎么優(yōu)化”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Android ListView列表怎么優(yōu)化這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。