简体   繁体   中英

how to Show Parsed Json in card Widget Flutter

I just entered the Flutter framework. And I'm new. And a problem with displaying information received from JSON, I was able to display the information on the console using the forEach but I could not display it in the card widget And whatever I did to display the products inside the card or list, I did not succeed and no code came to my mind and I had no idea. please help me with your own code

Future<List<Products>> fetchProduct() async {
  List<Products> prodList = [];
  final response = await http.get(Uri.parse(
      'https://firebasestorage.googleapis.com/v0/b/flutter-api-app.appspot.com/o/response.json?alt=media&token=32a77076-ce7f-4818-9354-514d6afb3c12'));

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    var jsonList = jsonDecode(response.body);
    for (var prod in jsonList) {
      prodList.add(Products.fromJson(prod));
    }

    prodList.forEach((element) {
      var obj = element;
      print(obj.name);
      var myimages = obj.images;
      myimages.forEach((image) {
        var srcImage = image.src;
        print(srcImage);
      });
    });

    return prodList;
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

class Products {
  Products({
    required this.id,
    required this.name,
    required this.slug,
    required this.permalink,
    required this.dateCreated,
    required this.price,
    required this.description,
    required this.images,
  });

  int id;
  String name;
  String slug;
  String permalink;
  DateTime dateCreated;
  String price;
  String description;
  List<Image> images;

  factory Products.fromJson(Map<String, dynamic> json) => Products(
        id: json["id"],
        name: json["name"],
        slug: json["slug"],
        permalink: json["permalink"],
        dateCreated: DateTime.parse(json["date_created"]),
        price: json["price"],
        description: json["description"],
        images: List<Image>.from(json["images"].map((x) => Image.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "slug": slug,
        "permalink": permalink,
        "date_created": dateCreated.toIso8601String(),
        "price": price,
        "description": description,
        "images": List<dynamic>.from(images.map((x) => x.toJson())),
      };
}

class Image {
  Image({
    required this.id,
    required this.src,
  });

  int id;
  String src;

  factory Image.fromJson(Map<String, dynamic> json) => Image(
        id: json["id"],
        src: json["src"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "src": src,
      };
}

void main() {
  runApp(const ShopApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo Product On Widget Card Or ListView',
      theme: ThemeData(
          primarySwatch: Colors.amber,
          visualDensity: VisualDensity.adaptivePlatformDensity),
      home: const ShopApp(),
    );
  }
}

class ShopApp extends StatefulWidget {
  const ShopApp({Key? key}) : super(key: key);

  @override
  _ShopAppState createState() => _ShopAppState();
}

class _ShopAppState extends State<ShopApp> {
  late Future<List<Products>> futureProducts;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    futureProducts = fetchProduct();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
          appBar: AppBar(
            title: const Text('Fetch Data Example'),
          ),
          body: Column(
            children: [],
          )),
    );
  }
}

First of all, you should know that there are many ways to do this. But for you to understand, I will answer according to the level of the code you shared here.

The why question is very important.

For example, Why? That's true, but you don't know why you're using it. Because the part you use is in the question you ask.

late Future<List<Products>> futureProducts;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    futureProducts = fetchProduct();
  }

You will use FutureBuilder. You are assigning it to a variable with initState so that you don't constantly refresh and draw.

Let's come to the answer to the question,

class _ShopAppState extends State<ShopApp> {
  late Future<List<Products>> futureProducts;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    futureProducts = fetchProduct();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
          appBar: AppBar(
            title: const Text('Fetch Data Example'),
          ),
          body: _buildBody()),
    );
  }

  Widget _buildBody(BuildContext context) {
    return FutureBuilder<List<Products>>(
        future: futureProducts,
        builder:
            (BuildContext context, AsyncSnapshot<List<Products>> snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return Text('Loading....');
            default:
              if (snapshot.hasError)
                return Text('Error: ${snapshot.error}');
              else
                return ListView.builder(
                    itemCount: snapshot.data?.length,
                    itemBuilder: (BuildContext context, int index) {
                      return Card(
                        child: Column(
                          children: [
                            ListTile(
                              title: Text('ID'),
                              subtitle: Text('${snapshot.data?[index].id}'),
                            ),
                            ListTile(
                              title: Text('NAME'),
                              subtitle: Text('${snapshot.data?[index].name}'),
                            ),
                            ListTile(
                              title: Text('SLUG'),
                              subtitle: Text('${snapshot.data?[index].name}'),
                            ),
                            ListTile(
                              title: Text('PERMALINK'),
                              subtitle: Text('${snapshot.data?[index].permalink}'),
                            ),

                            // bla bla bla.. other fields.
                          ],
                        ),
                      );
                    });
          }
        });
  }
}

The rest is in you, Good luck.

PS - Get used to parsing code as Model, Service or Provider, Controller, Constants, Widget, bla bla bla...

Do you like util? Data null control example..

class MyDataFormatter {
  String showEmptyIsNull({dynamic data, String text}) {
    if (data == null) {
      if (text == null) {
        return '';
      } else {
        return text;
      }
    } else {
      return '$data';
    }
  }
}

final myDataFormatter = MyDataFormatter();

myDataFormatter.showEmptyIsNull(data: snapshot.data?[index].name})

nice that Work, But My class "Products " has nested class "images" and values "id","src" How to Show this two value in Listtile Item?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM