问题
I am trying to build a news reader app using Flutter. However, the challenge I am facing is that I need to show different layouts based on the dimensions of the network image. I researched around this and couldn't find a solution. Please help.
回答1:
I somehow made a workaround not using the listview and using the singlechildscrollview in horizontal direction and list of row widgets. Just check out the example that I have made : I have taken the JSON data locally using the list of network images.
below is my local JSON(parse.json):
{
"apus_findgo_gallery_images": {
"2092": "http://www.camhalalguide.com/wp-content/uploads/2019/11/6b806c88-2f19-4054-914b-dee3c0c091eb.jpg",
"2093": "http://www.camhalalguide.com/wp-content/uploads/2019/11/24.1.1-phnom-chisor-temple.jpg",
"2096": "http://www.camhalalguide.com/wp-content/uploads/2019/11/image-asset.jpg",
"2098": "http://www.camhalalguide.com/wp-content/uploads/2019/11/phnom-chisor-01-600_orig.jpg",
"2099": "http://www.camhalalguide.com/wp-content/uploads/2019/11/phnom-chisor-02-600_orig.jpg",
"2100": "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg",
"2101":"https://images.ctfassets.net/4kwp3o37mlek/26EyWHHgDOS4qSCCmAWYuY/e4fd2b3c2054b06fafe7ddebca47d1a8/Apple_Logo.png",
"2102":"https://img.helpnetsecurity.com/wp-content/uploads/2015/12/09195727/1450275992_key-100x100.png",
"2103":"https://fakeimg.pl/200x100/282828/eae0d0/?retina=1",
"2104":"https://www.calliaweb.co.uk/wp-content/uploads/2015/10/600x200.jpg"
}
}
Below is the model class i have made :
// To parse this JSON data, do
//
// final yourModelClass = yourModelClassFromJson(jsonString);
import 'dart:convert';
YourModelClass yourModelClassFromJson(String str) => YourModelClass.fromJson(json.decode(str));
String yourModelClassToJson(YourModelClass data) => json.encode(data.toJson());
class YourModelClass {
Map<String, String> apusFindgoGalleryImages;
YourModelClass({
this.apusFindgoGalleryImages,
});
factory YourModelClass.fromJson(Map<String, dynamic> json) => YourModelClass(
apusFindgoGalleryImages: Map.from(json["apus_findgo_gallery_images"]).map((k, v) => MapEntry<String, String>(k, v)),
);
Map<String, dynamic> toJson() => {
"apus_findgo_gallery_images": Map.from(apusFindgoGalleryImages).map((k, v) => MapEntry<String, dynamic>(k, v)),
};
}
This is the main class that ia have made :
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sample_project_for_api/model.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> imagesList = List();
@override
void initState() {
super.initState();
yourMethod();
}
yourMethod() async {
String jsonString = await loadFromAssets();
final yourModelClass = yourModelClassFromJson(jsonString);
Map data = yourModelClass.apusFindgoGalleryImages;
List<String> list = new List();
data.forEach((key, value) {
list.add(value);
});
imagesList = list;
setState(() {});
}
Future<String> loadFromAssets() async {
return await rootBundle.loadString('json/parse.json');
}
Widget ImageCard(String data) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: MediaQuery.of(context).size.width * 0.97,
child: Card(
elevation: 5,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.network(
data,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent loadingProgress) {
if (loadingProgress == null) return child;
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes
: null,
),
);
},
),
),
],
)),
),
);
}
Widget _buildImageCards(List<String> product) {
final cards = <Widget>[];
Widget imageCards;
if (product.length > 0) {
for (int i = 0; i < product.length; i++) {
cards.add(ImageCard(product[i]));
print(product.length);
}
imageCards = Container(
padding: EdgeInsets.only(top: 16, bottom: 8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(children: cards),
),
],
),
);
} else {
imageCards = Container();
}
return imageCards;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.only(top: 16, bottom: 8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
_buildImageCards(imagesList),
],
),
),
],
),
));
}
}
来源:https://stackoverflow.com/questions/60390468/flutter-different-listview-itembuilder-layouts-based-on-network-image-dimension