我尝试使用Listview和Sliverlist,但我的列表的性能非常慢。即使项目是从互联网上加载的,滚动也非常慢。
有没有人对慢代码有什么想法?
import 'dart:typed_data';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:impex_shop/bloc/warenkorb_bloc.dart';
import 'package:impex_shop/data/articlepodo.dart';
import 'package:impex_shop/routenames.dart';
import 'package:impex_shop/services/repository.dart';
import 'package:impex_shop/styles/impex_icons.dart';
import 'package:impex_shop/styles/impex_styles.dart';
import 'package:impex_shop/utils/utils.dart';
import 'package:impex_shop/widgets/myfuturebuilder.dart';
class SearchResultsWidget extends StatefulWidget {
final Map<String, String> search;
SearchResultsWidget(this.search);
@override
_SearchResultsWidgetState createState() =>
_SearchResultsWidgetState(this.search);
}
class _SearchResultsWidgetState extends State<SearchResultsWidget> {
Map<String, String> search;
Future<ArticleIdList> _articleIds;
_SearchResultsWidgetState(this.search);
@override
void initState() {
super.initState();
_articleIds = Repository().queryArticleSearch(search);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _articleIds,
//showProgressIndicator: true,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
ArticleIdList articleIds = snapshot.data;
if (articleIds.articleIds.length == 0) {
return Container(
padding: EdgeInsets.symmetric(
horizontal: ImpexStyle.horizontalPadding),
child: Text('Kein Artikel gefunden'),
);
}
return CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
if (index == 0) {
return Container(
height: ImpexStyle.verticalPadding,
);
}
Future<Article> article = Repository()
.queryArticleDetails(articleIds.articleIds[index - 1]);
return MyFutureBuilder(
future: article,
builder: (context, article) {
return SearchResultLineWidget(article: article);
},
);
},
childCount: articleIds.articleIds.length + 1,
),
)
],
);
} else if (snapshot.hasError) {
return Row(
children: <Widget>[
Icon(
Icons.error,
color: ImpexColors.errorColor,
size: 30,
),
Expanded(
child: Text(
'${snapshot.error}',
style: TextStyle(color: ImpexColors.errorColor),
),
)
],
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
);
}
}
class SearchResultLineWidget extends StatefulWidget {
const SearchResultLineWidget({this.article});
final Article article;
@override
State<StatefulWidget> createState() {
return SearchResultLineState(article);
}
}
class SearchResultLineState extends State<SearchResultLineWidget> {
SearchResultLineState(this._article);
final Article _article;
Future<String> _articleImageData;
@override
void initState() {
super.initState();
_articleImageData = Repository().queryArticleImage(
_article.id,
width: ImpexStyle.imageSize,
height: ImpexStyle.imageSize,
);
}
@override
Widget build(BuildContext context) {
WarenkorbBloc warenkorbBloc = BlocProvider.of<WarenkorbBloc>(context);
bool isInWarenkorb = (warenkorbBloc.currentState as WarenkorbLoaded)
.warenkorbLines[_article.id] !=
null;
return Column(
children: <Widget>[
FlatButton(
onPressed: (() {
Navigator.pushNamed(context, RouteName.ARTICLE_DETAIL,
arguments: _article.id);
}),
child: Row(
children: <Widget>[
FutureBuilder<String>(
future: _articleImageData,
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.connectionState == ConnectionState.done) {
var imageData = snapshot.data;
if (imageData.isEmpty || imageData == 'null')
return Container(
width: ImpexStyle.imageSize.toDouble(),
height: ImpexStyle.imageSize.toDouble(),
child: EmptyImageIcon(),
);
return Container(
height: ImpexStyle.imageSize.toDouble(),
width: ImpexStyle.imageSize.toDouble(),
child: Stack(children: <Widget>[
Image(
image: MemoryImage(
Uint8List.fromList(imageData.codeUnits),
),
),
isInWarenkorb
? Icon(FontAwesomeIcons.shoppingCart)
: Center(),
]),
);
} else if (snapshot.hasError) {
return Container(
width: ImpexStyle.imageSize.toDouble(),
height: ImpexStyle.imageSize.toDouble(),
child: Text(snapshot.error),
);
}
return Container(
width: ImpexStyle.imageSize.toDouble(),
height: max(96, ImpexStyle.imageSize.toDouble()),
child: Center(),
);
},
),
Container(width: ImpexStyle.horizontalPadding),
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Text(
_article.no,
style: ImpexStyle.fontStyleSmall,
),
),
Spacer(),
PriceLagerWidget(_article),
],
),
Text(_article.name, style: ImpexStyle.fontStyleNormal)
],
),
)
],
),
),
Divider(color: ImpexColors.dividerColor),
],
);
}
}
class PriceLagerWidget extends StatelessWidget {
PriceLagerWidget(this._article)
: _articlePrice = Repository().queryArticlePrice(_article.id);
final Article _article;
final Future<ArticlePrice> _articlePrice;
@override
Widget build(BuildContext context) {
return MyFutureBuilder<ArticlePrice>(
future: _articlePrice,
builder: (context, articlePrice) {
String priceString = getPriceString(articlePrice, context);
return Row(
children: <Widget>[
Row(
children: <Widget>[
_article.isRaffleWin
? RaffleWinIcon()
: Text('€', style: ImpexStyle.fontStyleSmall),
Text(' $priceString ', style: ImpexStyle.fontStyleSmall)
],
),
AvailabilityIcon(this._article.availabilityColor)
],
);
},
);
}
}
2条答案
按热度按时间f3temu5u1#
我认为使用
ListView.builder
可能会对你有所帮助,因为它只渲染可见的项目。这是一篇关于widget optimization的文章,它解释了构建一些小部件时的性能差异。
qxsslcnc2#
ListView.builder(itemCount:rows,prototypeItem:ListTile(),itemBuilder:(context,index){ ListTile()}确保设置prototypeItem,否则性能仍然很差。