【问题标题】:Flutter : How to call Local JSON Data and added to Tabbar dinamically?Flutter:如何调用本地 JSON 数据并动态添加到标签栏?
【发布时间】:2022-01-21 06:39:36
【问题描述】:

我希望通过使用 JSON 来缩短我的代码。请帮忙,如何将本地 JSON 生成到 Tabbar 中?以前我读过这个网站的帖子,但它调用 JSON API,而不是 LOCAL JSON。我还是不明白怎么称呼它

我想要这样的应用

我的 JSON 文件 (assets/product.json)

[
{
    "id": 1,
    "title": "NoteBook",
    "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
    "image": "assets/img/notebook.jpg",
    "price": "Rp. 13.000.000"
},
{
    "id": 2,
    "title": "Printer",
    "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
    "image": "assets/img/printer.jpg",
    "price": "Rp. 700.000"
},
{
    "id": 3,
    "title": "Mouse",
    "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
    "image": "assets/img/standard-mouse.jpg",
    "price": "Rp. 1.100.000"
},
{
    "id": 4,
    "title": "Keyboard",
    "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
    "image": "assets/img/rgb-keyboard.jpg",
    "price": "Rp. 2.100.000"
},
{
    "id": 5,
    "title": "Mouse Gaming",
    "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
    "image": "assets/img/gaming-mouse.jpg",
    "price": "Rp. 500.000"
},
{
    "id": 6,
    "title": "Proccessor",
    "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
    "image": "assets/img/procie.jpg",
    "price": "Rp. 6.000.000"
},
{
    "id": 7,
    "title": "Solid State Drive",
    "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
    "image": "assets/img/ssd.jpg",
    "price": "Rp. 2.100.000"
}

]

我的产品模型 (ProductModel.dart)

import 'dart:convert';

List<Product> ProductFromJson(String str) =>
    List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));

class Product {
  Product({
    this.id,
    this.title,
    this.image,
    this.description,
    this.price,
  });
  final int id;
  final String title;
  final String image;
  final String description;
  final String price;

  factory Product.fromJson(Map<String, dynamic> json) => Product(
        id: json["id"],
        title: json["title"],
        image: json["image"],
        description: json["description"],
        price: json["price"],
      );

  String getTitle() {
    return title;
  }

  String getImage() {
    return image;
  }

  String getDescription() {
    return description;
  }

  String getPrice() {
    return price;
  }
}

我的主页(MainPage.dart)

import 'package:flutter/material.dart';

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

  @override
  State<MainPage> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage>
    with SingleTickerProviderStateMixin {
  TabController myTabController;

  List<Widget> myTabs = [];
  List<Widget> myTabsContent = [];

  @override
  void initState() {
    super.initState();
    myTabController = TabController(vsync: this, length: myTabs.length);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        titleSpacing: 10,
        title: Text("My Store"),
        bottom: TabBar(
          labelPadding: EdgeInsets.fromLTRB(20, 0, 20, 10),
          isScrollable: true,
          controller: myTabController,
          tabs: myTabs.toList(),
        ),
      ),
      body: TabBarView(
        controller: myTabController,
        children: myTabsContent.toList(),
      ),
    );
  }
}

【问题讨论】:

    标签: json flutter dart tabbar


    【解决方案1】:

    您可以尝试此方法从 json 加载产品并使用 FutureBuilder 加载内容并将其显示到您的标签:

        Future<List<Product>> _getProducts() async {
        // Load json from file system
        final dataString =
        await rootBundle.loadString('assets/product.json');
        // Decode to json
        final List<dynamic> json = jsonDecode(dataString);
    
        // Go through each post and convert json to Post object.
          final products = <Product>[];
          json.forEach((v) {
            products.add(Product.fromJson(v));
          });
          return products;
      }
    

    基于您的代码的示例(您需要更新代码以根据结果处理 myTabs 和 myTabsContent 的初始值):

    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class MainPage extends StatefulWidget {
      const MainPage({Key? key}) : super(key: key);
    
      @override
      State<MainPage> createState() => _MainPageState();
    }
    
    class _MainPageState extends State<MainPage>
        with SingleTickerProviderStateMixin {
      late TabController myTabController;
    
      List<Widget> myTabs = const [
        Tab(icon: Icon(Icons.directions_car)),
        Tab(icon: Icon(Icons.directions_transit)),
        Tab(icon: Icon(Icons.directions_bike)),
      ];
      List<Widget> myTabsContent = [];
    
      Future<List<Product>> _getProducts() async {
        // Load json from file system
        final dataString = await rootBundle.loadString('assets/product.json');
        // Decode to json
        final List<dynamic> json = jsonDecode(dataString);
    
        // Go through each post and convert json to Post object.
        final products = <Product>[];
        json.forEach((v) {
          products.add(Product.fromJson(v));
        });
        return products;
      }
    
      @override
      void initState() {
        super.initState();
        myTabController = TabController(vsync: this, length: myTabs.length);
      }
    
      @override
      Widget build(BuildContext context) {
        return FutureBuilder(
            future: _getProducts(),
            builder: (context, AsyncSnapshot<List<Product>> snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                return Scaffold(
                  appBar: AppBar(
                    titleSpacing: 10,
                    title: const Text("My Store"),
                    bottom: TabBar(
                      isScrollable: true,
                      controller: myTabController,
                      tabs: myTabs,
                    ),
                  ),
                  body: TabBarView(controller: myTabController, children: [
                    _buildItems(snapshot.data!.first),
                    Icon(Icons.directions_transit),
                    Icon(Icons.directions_bike),
                  ]),
                );
              } else {
                return const Icon(Icons.directions_car);
              }
            });
      }
    
      Widget _buildItems(Product product) {
        return Column(
          children: [
            Text(product.title),
            Text(product.price)
          ],
        );
      }
    }
    
    //
    
    List<Product> ProductFromJson(String str) =>
        List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
    
    class Product {
      Product({
        required this.id,
        required this.title,
        required this.image,
        required this.description,
        required this.price,
      });
    
      final int id;
      final String title;
      final String image;
      final String description;
      final String price;
    
      factory Product.fromJson(Map<String, dynamic> json) => Product(
            id: json["id"],
            title: json["title"],
            image: json["image"],
            description: json["description"],
            price: json["price"],
          );
    
      String getTitle() {
        return title;
      }
    
      String getImage() {
        return image;
      }
    
      String getDescription() {
        return description;
      }
    
      String getPrice() {
        return price;
      }
    }
    

    Here is result

    【讨论】:

    • 我收到错误消息_TypeError(类型'List'不是'Map'类型的子类型)
    • 我刚刚更新,重试
    【解决方案2】:

    这是我添加您的代码后的代码。但数据未显示:( Mr booykoquay

    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class MainPage extends StatefulWidget {
      const MainPage({Key key}) : super(key: key);
    
      @override
      State<MainPage> createState() => _MainPageState();
    }
    
    class _MainPageState extends State<MainPage>
        with SingleTickerProviderStateMixin {
      TabController myTabController;
    
      List<Widget> myTabs = [];
      List<Widget> myTabsContent = [];
    
      Future<List<Product>> _getProducts() async {
        // Load json from file system
        final dataString = await rootBundle.loadString('assets/product.json');
        // Decode to json
        final List<dynamic> json = jsonDecode(dataString);
    
        // Go through each post and convert json to Post object.
        final products = <Product>[];
        json.forEach((v) {
          products.add(Product.fromJson(v));
        });
        return products;
      }
    
      @override
      void initState() {
        super.initState();
        myTabController = TabController(vsync: this, length: myTabs.length);
      }
    
      @override
      Widget build(BuildContext context) {
        return FutureBuilder(
            future: _getProducts(),
            builder: (context, _) {
              return Scaffold(
                appBar: AppBar(
                  titleSpacing: 10,
                  title: const Text("My Store"),
                  bottom: TabBar(
                    isScrollable: true,
                    controller: myTabController,
                    tabs: myTabs.toList(),
                  ),
                ),
                body: TabBarView(
                  controller: myTabController,
                  children: myTabsContent.toList(),
                ),
              );
            });
      }
    }
    
    //
    
    List<Product> ProductFromJson(String str) =>
        List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
    
    class Product {
      Product({
        this.id,
        this.title,
        this.image,
        this.description,
        this.price,
      });
      final int id;
      final String title;
      final String image;
      final String description;
      final String price;
    
      factory Product.fromJson(Map<String, dynamic> json) => Product(
            id: json["id"],
            title: json["title"],
            image: json["image"],
            description: json["description"],
            price: json["price"],
          );
    
      String getTitle() {
        return title;
      }
    
      String getImage() {
        return image;
      }
    
      String getDescription() {
        return description;
      }
    
      String getPrice() {
        return price;
      }
    }
    

    【讨论】:

      【解决方案3】:

      问题已解决,这是我的代码

      import 'dart:convert';
      import 'package:flutter/material.dart';
      import 'package:flutter/services.dart';
      
      class MainPage extends StatefulWidget {
        const MainPage({Key key}) : super(key: key);
      
        @override
        State<MainPage> createState() => _MainPageState();
      }
      
      class _MainPageState extends State<MainPage>
          with SingleTickerProviderStateMixin {
        Future<List<Product>> _getProducts() async {
          final dataString = await rootBundle.loadString('assets/product.json');
          final List<dynamic> json = jsonDecode(dataString);
          final products = <Product>[];
          for (var v in json) {
            products.add(Product.fromJson(v));
          }
          return products;
        }
      
        @override
        Widget build(BuildContext context) {
          return FutureBuilder<List<Product>>(
            future: _getProducts(),
            builder: (c, s) {
              if (s.hasData) {
                List<Tab> tabs = <Tab>[];
      
                for (int i = 0; i < s.data.length; i++) {
                  tabs.add(Tab(
                    child: Text(
                      s.data[i].title,
                    ),
                  ));
                }
                return DefaultTabController(
                  length: s.data.length,
                  child: Scaffold(
                    appBar: AppBar(
                      title: const Text("My Store"),
                      bottom: TabBar(
                        isScrollable: true,
                        tabs: tabs,
                      ),
                    ),
                    body: FutureBuilder<List<Product>>(
                      future: _getProducts(),
                      builder: (c, s) {
                        if (s.hasData) {
                          List<Widget> tabs = <Widget>[];
      
                          for (int i = 0; i < s.data.length; i++) {
                            tabs.add(Tab(
                              child: SingleChildScrollView(
                                physics: const BouncingScrollPhysics(
                                    parent: AlwaysScrollableScrollPhysics()),
                                child: Padding(
                                  padding: const EdgeInsets.symmetric(
                                      horizontal: 20, vertical: 0),
                                  child: Column(
                                    mainAxisAlignment: MainAxisAlignment.start,
                                    children: [
                                      const SizedBox(height: 30),
                                      Text(
                                        s.data[i].title,
                                        textAlign: TextAlign.center,
                                        style: const TextStyle(
                                            fontSize: 20,
                                            fontWeight: FontWeight.bold),
                                      ),
                                      const SizedBox(height: 30),
                                      Image.asset(s.data[i].image),
                                      const SizedBox(height: 30),
                                      Text(s.data[i].title),
                                      const SizedBox(height: 30),
                                      Text(s.data[i].description),
                                    ],
                                  ),
                                ),
                              ),
                            ));
                          }
                          return TabBarView(
                            children: tabs,
                          );
                        }
                        return Container();
                      },
                    ),
                  ),
                );
              }
              return Scaffold(
                body: Center(
                    child: Text(s.hasError ? s.error.toString() : "Loading...")),
              );
            },
          );
        }
      }
      
      // Product Model
      
      List<Product> ProductFromJson(String str) =>
          List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
      
      class Product {
        Product({
          this.id,
          this.title,
          this.image,
          this.description,
          this.price,
        });
      
        final int id;
        final String title;
        final String image;
        final String description;
        final String price;
      
        factory Product.fromJson(Map<String, dynamic> json) => Product(
              id: json["id"],
              title: json["title"],
              image: json["image"],
              description: json["description"],
              price: json["price"],
            );
      
        String getTitle() {
          return title;
        }
      
        String getImage() {
          return image;
        }
      
        String getDescription() {
          return description;
        }
      
        String getPrice() {
          return price;
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-02-20
        • 2020-12-05
        • 2020-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-23
        • 2016-12-19
        相关资源
        最近更新 更多