【发布时间】:2021-06-02 01:27:40
【问题描述】:
我动态创建了一些选项卡功能。我只需要该动态函数中的 10 个选项卡,您就可以响应此方法的条件。
【问题讨论】:
-
欢迎使用 StackOverFlow,发布您的代码(最小、完整、可重现)以获得更有针对性的答案。
我动态创建了一些选项卡功能。我只需要该动态函数中的 10 个选项卡,您就可以响应此方法的条件。
【问题讨论】:
这是一个显示随机动态运动列表的小示例应用程序。
每个TabItem 都由name 和description 定义。
part '66457422.dynamic_tabs.freezed.dart';
@freezed
abstract class TabItem implements _$TabItem {
const factory TabItem({
String name,
String description,
}) = _TabItem;
const TabItem._();
String get initials =>
name.split(RegExp(r'\W+')).map((x) => x[0].toUpperCase()).join('');
static TabItem get random {
final faker = Faker();
return TabItem(
name: faker.sport.name(),
description: faker.lorem.sentence(),
);
}
}
我使用了freezed 包,它为我的TabItem 提供了不变性。 freezed 使用build_runner 包在66457422.dynamic_tabs.freezed.dart 内部生成类实现。
在我的 TabItem 中,我定义了 getters:
String get initials 获取要用作标签标签的每项运动的首字母缩写。faker 包,static TabItem get random 生成随机运动。要维护TabItems 的列表,您需要某种状态管理。在此示例中,我使用来自与 Provider 相同作者的 riverpod 包(在其 flutter_hooks 风格中)。但是,如果您愿意,可以使用其他状态管理系统。检查这个curated list。
我的tabsProvider 是一个StateNotifierProvider,定义如下:
final tabsProvider = StateNotifierProvider<TabsNotifier>(
(ref) => TabsNotifier()..addTab()..addTab()..addTab());
class TabsNotifier extends StateNotifier<List<TabItem>> {
TabsNotifier([List<TabItem> state]) : super(state ?? []);
void addTab() {
state = [
...state,
TabItem.random,
];
}
}
现在,我们只需要显示所有内容!
我使用DefaultTabController Widget 并在我的tabsProvider 提供的List<TabItem> 上映射以显示Tabs 和TabViews:
class HomePage extends HookWidget {
@override
Widget build(BuildContext context) {
final tabs = useProvider(tabsProvider.state);
return DefaultTabController(
length: tabs.length,
child: Scaffold(
appBar: AppBar(
title: Text('Dynamic Tabs Demo'),
bottom: TabBar(
tabs: tabs.map((t) => Tab(text: t.initials)).toList(),
),
),
body: TabBarView(
children: tabs.map((t) => TabItemWidget(tabItem: t)).toList(),
),
floatingActionButton: tabs.length >= 10
? null
: FloatingActionButton(
onPressed: () => context.read(tabsProvider).addTab(),
child: Icon(Icons.add),
),
),
);
}
}
仅当TabItems 的数量小于10 时,FloatingActionButton 才会在我的tabsProvider 上出现addTab()。否则,它会消失。
瞧!就是这样。
import 'package:faker/faker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
part '66457422.dynamic_tabs.freezed.dart';
void main() {
runApp(
ProviderScope(
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Dynamic Tabs Demo',
home: HomePage(),
),
),
);
}
class HomePage extends HookWidget {
@override
Widget build(BuildContext context) {
final tabs = useProvider(tabsProvider.state);
return DefaultTabController(
length: tabs.length,
child: Scaffold(
appBar: AppBar(
title: Text('Dynamic Tabs Demo'),
bottom: TabBar(
tabs: tabs.map((t) => Tab(text: t.initials)).toList(),
),
),
body: TabBarView(
children: tabs.map((t) => TabItemWidget(tabItem: t)).toList(),
),
floatingActionButton: tabs.length >= 10
? null
: FloatingActionButton(
onPressed: () => context.read(tabsProvider).addTab(),
child: Icon(Icons.add),
),
),
);
}
}
class TabItemWidget extends StatelessWidget {
final TabItem tabItem;
const TabItemWidget({Key key, this.tabItem}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
Text(tabItem.name),
const SizedBox(height: 24.0),
Text(tabItem.description),
],
),
);
}
}
final tabsProvider = StateNotifierProvider<TabsNotifier>(
(ref) => TabsNotifier()..addTab()..addTab()..addTab());
class TabsNotifier extends StateNotifier<List<TabItem>> {
TabsNotifier([List<TabItem> state]) : super(state ?? []);
void addTab() {
state = [
...state,
TabItem.random,
];
}
}
@freezed
abstract class TabItem implements _$TabItem {
const factory TabItem({
String name,
String description,
}) = _TabItem;
const TabItem._();
String get initials =>
name.split(RegExp(r'\W+')).map((x) => x[0].toUpperCase()).join('');
static TabItem get random {
final faker = Faker();
return TabItem(
name: faker.sport.name(),
description: faker.lorem.sentence(),
);
}
}
【讨论】: