I tried using Listview and Sliverlist, but the performance of my list is very slow. Even if the Items are loaded from the internet, the scrolling is very slow.
Anybody some thoughts about the slow code?
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)
],
);
},
);
}
}