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(), ), ) ], ), ); } }