问题描述
TabBarView是由对应的ListView构建而成,每个ListView中的Item实际上又由不同的component通过Abdapter动态构建,在使用过程中有如下问题:
- 当切换非连续的tab时,会报以下错误
type 'DiscoveryItemState' is not a subtype of type 'DesignItemState'

- 已添加KeepAliveWidget来解决Listview来保持页面状态,但是无效,依然会BuildItem。
数据结构
enum ItemType {
none,
design,
recruit,
discovery,
}
class ItemModel {
ItemType type = ItemType.none;
}
abstract class GlobalItem<T extends GlobalItem<T>> extends Cloneable<T> {
ItemModel item;
}
class RecruitItemState implements GlobalItem<RecruitItemState> {
ItemModel item = new ItemModel()..type = ItemType.recruit;
}
class DiscoveryItemState implements GlobalItem<DiscoveryItemState> {
ItemModel item = new ItemModel()..type = ItemType.discovery;
}
class DesignItemState implements GlobalItem<DesignItemState> {
ItemModel item = new ItemModel()..type = ItemType.design;
}
Adapter代码
class HomeListItemAdapter extends DynamicFlowAdapter<HomeState> {
HomeListItemAdapter()
: super(
pool: <String, Component<Object>>{
'DiscoveryItem': DiscoveryItemComponent(),
'RecruitItem': RecruitItemComponent(),
'DesignItem': DesignItemComponent(),
},
connector: _HomeListItemConnector(),
);
}
class _HomeListItemConnector extends ConnOp<HomeState, List<ItemBean>> {
@override
List<ItemBean> get(HomeState state) {
// List<List<Object>> tabList; // Object是GlobalItem的子类
// Map<int, String> tabs; // tabs会动态从服务器中获取,其中Key决定了tabList对应要获取的内容
if (state.tabs?.isNotEmpty == true && state.tabList?.isNotEmpty == true) {
return state.tabList[state.currentIndex].map<ItemBean>((itemState) {
println(itemState.toString());
String itemType;
// 根据state中存储的的type类型动态生成Componet
switch ((itemState as GlobalItem).item.type) {
case ItemType.design:
itemType = 'DesignItem';
break;
case ItemType.recruit:
itemType = 'RecruitItem';
break;
case ItemType.discovery:
itemType = 'DiscoveryItem';
break;
default:
itemType = 'DesignItem';
break;
}
if (itemType.isNotEmpty) {
return ItemBean(itemType, itemState);
} else {
return null;
}
}).toList();
} else {
return <ItemBean>[];
}
}
}
View使用
Widget buildView(HomeState state, Dispatch dispatch, ViewService viewService) {
final adapter = viewService.buildAdapter();
println("适配器的数量:${adapter.itemCount}");
return Scaffold(
// resizeToAvoidBottomPadding: false,
backgroundColor: Color(0xFFF5F5F5),
body: Container(
height: 1000,
child: CustomScrollView(
controller: state.customScrollViewController,
slivers: <Widget>[
_buildSliverAppBar(state, viewService),
SliverList(
delegate: SliverChildListDelegate(
[
_buildMyApplication(),
Container(
padding: EdgeInsets.only(
top: 15, left: _leftAndRight, right: _leftAndRight),
child: viewService.buildComponent('middleBanner'),
),
_buildHotTopic(state),
Container(
padding: EdgeInsets.only(top: 32),
child: state.tabController == null
? LoadingView()
: _buildTabBar(
state,
dispatch,
viewService.context,
),
),
],
),
),
SliverFillRemaining(
child: Container(
child: state.tabController == null
? LoadingView()
: TabBarView(
// physics: NeverScrollableScrollPhysics(), // 禁滑动事件
controller: state.tabController,
// *******异常*********
children: state.tabs.keys.map((v) {
return KeepAliveWidget(
Container(
child: ListView.builder(
// controller: ,TODO: 用于控制列表被拉上去了,禁止滑动事件
itemBuilder: adapter.itemBuilder,
itemCount: adapter.itemCount,
),
),
);
}).toList(),
),
),
)
],
),
),
);
}
期望
- TabbarView中的每个ListView中展现的Item可以不一样
- 每个ListView中可以有不同Item
- 能正确保持页面状态,能正确切换