简体   繁体   English

如何在Flutter中创建动态标签栏?

[英]How to create a dynamic tab bar in Flutter?

I have two tabs that are built from the repository class.我有两个从存储库 class 构建的选项卡。 I need to filter the items that are shown on them according to nationalities, but the items are rendered only on the first tab.我需要根据国籍过滤显示在它们上的项目,但这些项目仅在第一个选项卡上呈现。 The second tab doesn't show anything, I believe it has to do with Stateful and Stateless.第二个选项卡没有显示任何内容,我相信它与有状态和无状态有关。

How can I run repository class each time I change tab?每次更改选项卡时,如何运行存储库 class?

The code below is about Tab and TabView下面的代码是关于 Tab 和 TabView

import 'package:flutter/material.dart';
import 'package:flutterbol/models/teams_model.dart';
import 'package:flutterbol/repository/teams_repository.dart';

class TeamsScreen extends StatefulWidget {
  @override
  _TeamsScreenState createState() => _TeamsScreenState();
}

class _TeamsScreenState extends State<TeamsScreen> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: choices.length,
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Tabbed AppBar'),
            bottom: TabBar(
              isScrollable: true,
              tabs: choices.map((Choice choice) {
                return Tab(
                  text: choice.title,
                  icon: Icon(choice.icon),
                );
              }).toList(),
            ),
          ),
          body: TabBarView(
            children: choices.map((Choice choice) {
              return Padding(
                padding: const EdgeInsets.all(16.0),
                child: ChoiceCard(choice: choice),
              );
            }).toList(),
          ),
        ),
      ),
    );
  }
}

class Choice {
  const Choice({this.title, this.icon});

  final String title;
  final IconData icon;
}

const List<Choice> choices = const <Choice>[
  const Choice(title: 'NATIONALS', icon: Icons.flag),
  const Choice(title: 'INTERNATIONALS', icon: Icons.outlined_flag),
];

class ChoiceCard extends StatelessWidget {
  const ChoiceCard({Key key, this.choice}) : super(key: key);

  final Choice choice;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: FutureBuilder<List<TeamsModel>>(
          future: TeamsRepository().findAllAsync(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              return buildListView(snapshot.data);
            } else {
              return Center(
                child: CircularProgressIndicator(),
              );
            }
          },
        ));
  }

  ListView buildListView(List<TeamsModel> teams) {
    return ListView.builder(
      itemCount: teams == null ? 0 : teams.length,
      //itemCount: teams.length,
      itemBuilder: (BuildContext ctx, int index) {
        return teamCard(teams[index]);
      },
    );
  }

  Card teamCard(TeamsModel team) {
    if (team.nacionalidade == choice.title) {
      return Card(
        child: Text(team.name),
      );
    }
  }
}

Tabs and Cards标签和卡片

You can copy paste run full code below您可以在下面复制粘贴运行完整代码
You need to return Container() in else condition and return type is Widget not Card您需要在else条件下return Container()并且返回类型是Widget而不是Card
code snippet代码片段

  Widget teamCard(TeamsModel team) {
    if (team.nacionalidade == choice.title) {
      return Card(
        child: Text(team.name),
      );
    } else {
      return Container();
    }
  }

working demo工作演示

在此处输入图像描述

full code完整代码

import 'package:flutter/material.dart';

class TeamsModel {
  String nacionalidade;
  String name;

  TeamsModel(this.name, this.nacionalidade);
}

class TeamsRepository {
  Future<List<TeamsModel>> findAllAsync() {
    return Future.value([
      TeamsModel("a", "NATIONALS"),
      TeamsModel("b", "NATIONALS"),
      TeamsModel("c", "INTERNATIONALS"),
      TeamsModel("d", "INTERNATIONALS")
    ]);
  }
}

class TeamsScreen extends StatefulWidget {
  @override
  _TeamsScreenState createState() => _TeamsScreenState();
}

class _TeamsScreenState extends State<TeamsScreen> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: choices.length,
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Tabbed AppBar'),
            bottom: TabBar(
              isScrollable: true,
              tabs: choices.map((Choice choice) {
                return Tab(
                  text: choice.title,
                  icon: Icon(choice.icon),
                );
              }).toList(),
            ),
          ),
          body: TabBarView(
            children: choices.map((Choice choice) {
              print(choice.title);
              return Padding(
                padding: const EdgeInsets.all(16.0),
                child: ChoiceCard(choice: choice),
              );
            }).toList(),
          ),
        ),
      ),
    );
  }
}

class Choice {
  const Choice({this.title, this.icon});

  final String title;
  final IconData icon;
}

const List<Choice> choices = const <Choice>[
  const Choice(title: 'NATIONALS', icon: Icons.flag),
  const Choice(title: 'INTERNATIONALS', icon: Icons.outlined_flag),
];

class ChoiceCard extends StatelessWidget {
  const ChoiceCard({Key key, this.choice}) : super(key: key);

  final Choice choice;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: FutureBuilder<List<TeamsModel>>(
      future: TeamsRepository().findAllAsync(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return buildListView(snapshot.data);
        } else {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
      },
    ));
  }

  ListView buildListView(List<TeamsModel> teams) {
    return ListView.builder(
      itemCount: teams == null ? 0 : teams.length,
      //itemCount: teams.length,
      itemBuilder: (BuildContext ctx, int index) {
        return teamCard(teams[index]);
      },
    );
  }

  Widget teamCard(TeamsModel team) {
    if (team.nacionalidade == choice.title) {
      return Card(
        child: Text(team.name),
      );
    } else {
      return Container();
    }
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: TeamsScreen(),
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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