I would like to pass a dynamic number of image url’s from my mysql database to a PageView Widget as a simple ImageSlider.
Problem: Several type errors like “the argument type ‘List(ImageList)’ can’t be assigned to the parameter type String.” OR “type List(dynamic) is not a subtype of type List(String)”etc., if i pass the selection to the Widget.
Question: How can i pass the selection from database to a PageView Widget? Do i have to change my sql-selection?
Below my short code example with a static list (what’s working fine):
final _images = ["url1","url2",];
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 16 / 9,
child: PageView(
physics: BouncingScrollPhysics(),
controller: _pageController,
children: _images.map((item) => Image.network(item,)).toList(),
),
);
}
What i tried so far:
Select from database as json or as string (GROUP_CONCAT(image)) –> no success
Changing the data types in Future for php-download –> no success
Trying to pass as String or List(String) to the map –> no success
Would be great if someone has an idea. If more code/answers are needed, please comment. Thank you very much.
Advertisement
Answer
//this is the first part from link in the comment above
List<Payload> payloadFromJson(String str) => List<Payload>.from(json.decode(str).map((x) => Payload.fromJson(x)));
String payloadToJson(List<Payload> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Payload {
String sponsorlogo;
Payload({
this.sponsorlogo,
});
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
sponsorlogo: json["image"] == null ? null : json["image"],
);
Map<String, dynamic> toJson() => {
"image": sponsorlogo == null ? null : sponsorlogo,
};
}
//now the second part looks like these
Future<List<Payload>> dlimagelist(String idaddress) async {
var map = Map<String, dynamic>();
map['idaddress'] = idaddress;
final response = await post("<url>.php", body: map);
var payloadList = payloadFromJson(response.body);
return payloadList;
}
//the third part is my future builder where i select with the cutomer id 'idaddress' or widget.id
body: FutureBuilder(
future: Future.wait(
[download1('${widget.id}'), download2('${widget.id}'), dlimagelist('${widget.id}')]),
builder: (context, snapshot) {
List<Payload> imagelist = snapshot.data[2];
return Scrollbar(
controller: _controller,
child: ListView(
children: [
if (imagelist.isNotEmpty) SliderWidget(imagelist) else StandardImage(snapshot.data[0]),
//some other widgets
],
),
);
},
),
//the last part is my Widget
class SliderWidget extends StatefulWidget {
final List<Payload> list;
SliderWidget(this.list);
@override
_SliderWidgetState createState() => _SliderWidgetState();
}
class _SliderWidgetState extends State<SliderWidget> {
PageController _pageController = PageController(initialPage: 1);
int _currentIndex = 1;
@override
Widget build(BuildContext context) {
final _images = widget.list;
List addedImages = [];
if (_images.length > 0) {
addedImages
..add(_images[_images.length - 1])
..addAll(_images)
..add(_images[0]);
}
return AspectRatio(
aspectRatio: 16 / 8,
child: Stack(
children: [
PageView(
physics: BouncingScrollPhysics(),
controller: _pageController,
onPageChanged: (page) {
int newIndex;
if (page == addedImages.length - 1) {
newIndex = 1;
_pageController.jumpToPage(newIndex);
} else if (page == 0) {
newIndex = addedImages.length - 2;
_pageController.jumpToPage(newIndex);
} else {
newIndex = page;
}
setState(() {
_currentIndex = newIndex;
});
},
children: addedImages
.map((item) => Container(
margin: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.network(
item.sponsorlogo,
fit: BoxFit.contain,
),
),
))
.toList(),
),
Positioned(
bottom: 5,
left: 0,
right: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: _images
.asMap()
.map((i, v) => MapEntry(
i,
Container(
width: 6,
height: 6,
margin: EdgeInsets.only(left: 2, right: 2),
decoration: ShapeDecoration(
color: _currentIndex == i + 1 ? Colors.red : Colors.white,
shape: CircleBorder(),
),
)))
.values
.toList(),
),
)
],
),
);
}
}