首页 > 解决方案 > 如何在颤动中动态创建选项卡

问题描述

标签图片链接目前我有 3 个标签,分别标有餐食、饮料和其他标签。但我希望根据从我的 api 响应中获取的记录数动态创建选项卡。示例:如果我的 api 响应是这样的

    {
        category: "Ice Cream",
    }
    {
        category: "Pizza",
    }
      {
        category: "Hot-dog",
    }
   {
        category: "Fish",
    }

所以它应该创建 4 个选项卡,因为它返回 4 个数据响应,并且该选项卡应该标记为类别响应数据。请问我怎样才能做到这一点?

这是我的代码

我的模特

class Category{
  String category_name


  CategoryMenu.fromJson(Map<String, dynamic> jsonObject) {
    this.category = jsonObject['category'].toString();
  }
}

我的类别 API

Future<List<Category>> getTabs() async {
    String cat = ApiUtil.MAIN_API_URL + ApiUtil.GET_TABS;
    Map<String, String> headers = {'Accept': 'application/json'};
    var response = await http.get(cat, headers: headers);

    List<Category> categories = [];
    if (response.statusCode == 200) {
      var body = jsonDecode(response.body);
      for (var item in body) {
        Category category = Category.fromJson(item);
        categories.add(category);
      }
    }
    return categories;
  }

我的屏幕

    class GetTabs extends StatefulWidget {
  @override
  _GetTabsState createState() => _GetTabsState();
}

class _GetTabsState extends State<GetTabs> {
  CategoryAPI catApi = new CategoryAPI();
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: catApi.getTabs(),
      builder:
          (BuildContext context, AsyncSnapshot<List<CategoryMenu>> snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.active:
            return _loading();
            break;
          case ConnectionState.waiting:
            return _loading();
            break;
          case ConnectionState.none:
            return _error('No connection has been made');
            break;
          case ConnectionState.done:
            if (snapshot.hasError) {
              return _error(snapshot.error.toString());
            }
            if (snapshot.hasData) {
              return buildDefaultTab(snapshot.data, context);
            }
            break;
        }
        return Container();
      },
    );
  }

  Widget buildDefaultTab(List<CategoryMenu> data, BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          backgroundColor: Color(0xffFDC054),
          elevation: 0,
          leading: IconButton(
            icon: Icon(
              Icons.arrow_back,
              color: Colors.white,
            ),
            onPressed: () => Navigator.of(context).pop(),
          ),
          brightness: Brightness.light,
          actions: <Widget>[
            IconButton(
                icon: Icon(
                  Icons.shopping_cart,
                  color: Colors.white,
                ),
                onPressed: () {
                  Navigator.push(context, ScaleRoute(page: FoodOrderPage()));
                })
          ],
        ),
        body: Container(
          padding: EdgeInsets.only(
            left: 15,
            right: 15,
          ),
          child: SingleChildScrollView(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                Card(
                  semanticContainer: true,
                  clipBehavior: Clip.antiAliasWithSaveLayer,
                  child: Image.asset(
                    'assets/images/vendors/' + 'crab' + ".jfif",
                  ),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(3.0),
                  ),
                  elevation: 1,
                  margin: EdgeInsets.all(5),
                ),
                VendorTitleWidget(
                  vendorName: "Chicken Republic",
                  //vendorName: widget.restaurant_id,
                  minOrderPrice: "\#800",
                  vendorRating: "4.6",
                  vendorLocation: "Uzi Road",
                ),
                SizedBox(
                  height: 15,
                ),
                AddToCartMenu(),
                SizedBox(
                  height: 15,
                ),
                PreferredSize(
                  preferredSize: Size.fromHeight(50.0),
                  child: TabBar(
                    labelColor: Color(0xffFDC054),
                    indicatorColor: Color(0xFFfd3f40),
                    unselectedLabelColor: Color(0xFFa4a1a1),
                    indicatorSize: TabBarIndicatorSize.label,
                    labelStyle: TextStyle(
                      fontWeight: FontWeight.w500,
                    ),
                    tabs: [
                      Tab(
                        text: 'Meals',
                      ),
                      Tab(
                        text: 'Drinks',
                      ),
                      Tab(
                        text: 'Others',
                      ),
                    ], // list of tabs
                  ),
                ),
                Container(
                  //height: 250,
                  height: MediaQuery.of(context).size.height / 1.5,
                  //width: MediaQuery.of(context).size.width,
                  child: TabBarView(
                    children: [
                      Container(
                        color: Colors.white24,
                        child: MealsTab(),
                      ),
                      Container(
                        color: Colors.white24,
                        child: DrinksTab(),
                        // DetailContentMenu(),
                      ),
                      Container(
                        color: Colors.white24,
                        child: ListViewPage(),
                      ), // class name
                    ],
                  ),
                ),
                //BottomMenu(),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

标签: flutter

解决方案


您可以创建两个函数来返回一个小部件数组,并在每个函数中迭代您的对象数组,以便您可以自定义每个选项卡和选项卡视图。

例如:

tabs: getTabs(List<Category> categories)(数据类型是一个例子)

List<Widget> getTabs(List<Category> categories) {
 return categories.map(category => {
   Container(
    child: Text(category.category) // In reference to the object that you have defined, but it should be called name.
   );
  }
 );
}

TabBarView 也是如此。

请记住,您可以返回任何类型的 Widget,我将返回一个容器作为示例。


推荐阅读