保留选项卡视图页面之间的状态

问题描述 投票:4回答:4

issue

我使用ListViewsTabBarView内部有两个TabController渲染。

如何在每个ListView之间保留状态(缺少一个更好的词),以便:1)小部件不重建和2.)在标签之间记住ListView位置。

relevant code

class AppState extends State<App> with SingleTickerProviderStateMixin {
  TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = new TabController(
      vsync: this,
      length: _allPages.length,
    );
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  Widget _buildScaffold(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('headlines'),
        bottom: new TabBar(
            controller: _tabController,
            isScrollable: true,
            tabs: _allPages
                .map((_Page page) => new Tab(text: page.country))
                .toList()),
      ),
      body: new TabBarView(
          controller: _tabController,
          children: _allPages.map((_Page page) {
            return new SafeArea(
              top: false,
              bottom: false,
              child: new Container(
                key: new ObjectKey(page.country),
                child: new Newsfeed(country: page.country),
              ),
            );
          }).toList()),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'news app',
      home: _buildScaffold(context),
    );
  }
}

illustrating gif

https://media.giphy.com/media/2ysWhzqHVqL1xcBlBE/giphy.gif

dart flutter
4个回答
6
投票

简而言之,对你的ListView或其中一个祖先使用PageStorageKey(),在你的情况下使用Container小部件:

child: new Container(
    key: new PageStorageKey(page.country),
    child: new Newsfeed(country: page.country),
),

详情请见:


17
投票

如果您想在TabBarView中保持屏幕状态,可以在State类中使用名为AutomaticKeepAliveClientMixin的mixin类。

之后你必须覆盖wantKeepAlive方法并返回true

我在这里写了一篇关于它的帖子:https://medium.com/@diegoveloper/flutter-persistent-tab-bars-a26220d322bc


0
投票

尝试在具有偏移量的堆栈中包含子视图。它帮助我保存了我的底栏导航状态。


0
投票

我遵循了这些建议而没有工作,所以我创建了自己的建议。到目前为止它的效果很好。

我的解决方案 基本上只是一个水平ListView,禁用滚动和元素上的最大宽度。我正在使用一个非常重的标签(谷歌地图)进行测试,它的效果非常好。

列表视图与所述元素:

  Widget body(BuildContext context) {
    final double width = MediaQuery.of(context).size.width;

    return ListView(
      controller: scrollController,
      scrollDirection: Axis.horizontal,
      physics: NeverScrollableScrollPhysics(),
      children: <Widget>[
        Container(width: width, child: TabLiveEvents()),
        Container(width: width, child: TabEvents()),
      ],
    );
  }

标签栏布局。

  Widget bottomNavbar(BuildContext context) {
    return BottomNavigationBar(
      items: [
        BottomNavigationBarItem(
            icon: Icon(Icons.chat_bubble),
            title: Text(Translation.tabMeetupText)),
        BottomNavigationBarItem(
            icon: Icon(Icons.list), title: Text(Translation.tabEventslist)),
      ],
      currentIndex: _selectedIndex,
      fixedColor: Theme.of(context).accentColor,
      onTap: _onItemTapped,
    );
  }

通过点击项目切换列表视图时..

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });

    double width = MediaQuery.of(context).size.width * index;
    scrollController.jumpTo(width);
  }

主小部件

@override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: appBar(),
        bottomNavigationBar: bottomNavbar(context),
        body: body(context),
      ),
    );
  }
© www.soinside.com 2019 - 2024. All rights reserved.