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

Android ListView列表優(yōu)化的方法詳解

 更新時間:2022年05月17日 12:32:06   作者:島上碼農  
列表 ListView 是應用中最為常見的組件,而列表往往也會承載很多元素,這時就需要對其進行優(yōu)化。本文介紹了 Flutter ListView 的4個優(yōu)化要點,非常實用,需要的可以參考一下

前言

列表 ListView 是應用中最為常見的組件,而列表往往也會承載很多元素,當元素多,尤其是那種圖片文件比較大的場合,就可能會導致列表卡頓,嚴重的時候可能導致應用崩潰。本篇來介紹如何優(yōu)化列表。

優(yōu)化點1:使用 builder構建列表

當你的列表元素是動態(tài)增長的時候(比如上拉加載更多),請不要直接用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.

優(yōu)化點2:禁用 addAutomaticKeepAlives 和 addRepaintBoundaries 特性

這兩個屬性都是為了優(yōu)化滾動過程中的用戶體驗的。addAutomaticKeepAlives 特性默認是 true,意思是在列表元素不可見后可以保持元素的狀態(tài),從而在再次出現(xiàn)在屏幕的時候能夠快速構建。這其實是一個拿空間換時間的方法,會造成一定程度的內存開銷??梢栽O置為 false 關閉這一特性。缺點是滑動過快的時候可能會出現(xiàn)短暫的白屏(實際會很少發(fā)生)。

addRepaintBoundaries 是將列表元素使用一個重繪邊界(Repaint Boundary)包裹,從而使得滾動的時候可以避免重繪。而如果列表很容易繪制(列表元素布局比較簡單的情況下)的時候,可以關閉這個特性來提高滾動的流暢度。

addAutomaticKeepAlives:?false,
addRepaintBoundaries:?false,

優(yōu)化點3:盡可能將列表元素中不變的組件使用 const 修飾

使用 const 相當于將元素緩存起來實現(xiàn)共用,若列表元素某些部分一直保持不變,那么可以使用 const 修飾。

return?Padding(
??child:?Row(
????children:?[
??????const?ListImage(),
??????const?SizedBox(
????????width:?5.0,
??????),
??????Text('第$index?個元素'),
????],
??),
??padding:?EdgeInsets.all(10.0),
);

優(yōu)化點4:使用 itemExtent 確定列表元素滾動方向的尺寸

對于很多列表,我們在滾動方向上的尺寸是提前可以根據 UI設計稿知道的,如果能夠知道的話,那么使用 itemExtent 屬性制定列表元素在滾動方向的尺寸,可以提升性能。這是因為,如果不指定的話,在滾動過程中,會需要推算每個元素在滾動方向的尺寸從而消耗計算資源。

itemExtent:?120,

優(yōu)化實例

下面是一開始未改造的列表,嗯,可以認為是垃圾代碼

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://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7869eac08a7d4177b600dc7d64998204~tplv-k3u1fbpfcp-watermark.jpeg',
??????????????????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://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7869eac08a7d4177b600dc7d64998204~tplv-k3u1fbpfcp-watermark.jpeg',
??????width:?200,
????);
??}
}

總結

本篇介紹了 Flutter ListView 的4個優(yōu)化要點,非常實用哦!實際上,這些要點都可以從官網的文檔里找出對應的說明。因此,如果遇到了性能問題,除了搜索引擎外,也建議多看看官方的文檔。另外一個,對于列表圖片,有時候也需要前后端配合,比如目前的手機都是號稱1億像素的,如果上傳的時候直接上傳原圖,那么加載如此大的圖片肯定是非常消耗資源的。對于這種情況,建議是生成列表縮略圖(可能需要針對不同屏幕尺寸生成不同的縮略圖)。

以上就是Android ListView列表優(yōu)化的方法詳解的詳細內容,更多關于Android ListView列表優(yōu)化的資料請關注腳本之家其它相關文章!

相關文章

最新評論