当用户在Flutter中向下滚动Tab1时,如何防止Tab2自动向下滚动?

时间:2019-02-12 09:53:40

标签: flutter flutter-layout flutter-sliver

我使用SliverAppBarSliverPersistentHeaderTabViewListView创建了一个屏幕。

如果我在tab1中向下滚动,则tab2自动向下滚动。因此,如果我切换到tab2,则列表不是从第一项开始。我该如何预防?

我创建了一个简单的演示应用程序来演示该问题,您可以查看此gist

屏幕的初始状态: 1

如果我滚动如下所示的tab1: 2

在滚动tab1时,Tab2自动向下滚动,如下所示: 3

4 个答案:

答案 0 :(得分:0)

此问题背后的原因是,两个标签都使用相同的TabController(在您的情况下为DefaultTabController,这是为子窗口小部件非强制性地定义标签控制器,您必须显式设置单独的{{ 1}},以便每个选项卡的操作都独立于其他选项卡,但是您将需要额外的代码来管理新的控制器:

这是示例:

在您的TabController

nestedScrollView

答案 1 :(得分:0)

尝试将TabBarView包装在StatefulWidget内的单独支架中。这样,您可以确保每次更改标签时都重新构建标签主体,这样就不会保留滚动位置。

示例:

return Scaffold(
  body: DefaultTabController(
    length: 2,
    child: NestedScrollView(
      headerSliverBuilder: /* Your headerSliverBuilder code */
      body: MyCustomTabWidget(),
    )
);

class MyCustomTabWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return MyCustomTabWidgetState();
  }
}

class MyCustomTabWidgetState extends State<MyCustomTabWidget > {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: new TabBarView(
        children: [
          /*Code for both the Containers containing ListViews*/
        ]
      )
    )
  }
}

答案 2 :(得分:0)

在这里查看我的解决方法: https://stackoverflow.com/a/54696347/3542938 仍然不是最好的,但是解决它的更好的方法 尝试进行改进,并与我们分享代码

答案 3 :(得分:0)

我已经用PageStorageKey修改了您的gist。参见以下工作示例:

import 'package:flutter/material.dart';

void main() async {
    runApp(new TestApp());
}


class TestApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return new MaterialApp(
            theme: new ThemeData(primarySwatch: Colors.yellow),
            home: new TestAppHomePage(),
        );
    }
}

class TestAppHomePage extends StatefulWidget {

    @override
    State createState() => new TestAppHomePageState();
    //FPDetailScreen({Key key, @required this.period}) : super(key: key);
}

class TestAppHomePageState extends State<TestAppHomePage>
        with SingleTickerProviderStateMixin {

    @override
    Widget build(BuildContext context) {

        return new Scaffold(
            //bottomNavigationBar: bottomNavBar,
            body: DefaultTabController(
                length: 2,
                child: NestedScrollView(
                    headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
                        return <Widget>[
                            SliverAppBar(
                                expandedHeight: 120.0,
                                floating: false,
                                forceElevated: innerBoxIsScrolled,
                                backgroundColor: Colors.green,
                                pinned: true,
                                flexibleSpace: FlexibleSpaceBar(
                                    collapseMode: CollapseMode.pin,
                                    centerTitle: true,
                                    title: Text(
                                        "Foo Bar Baz",
                                        style: TextStyle(color: Colors.white),
                                        textAlign: TextAlign.left,
                                        overflow: TextOverflow.ellipsis,
                                        softWrap: true,
                                        maxLines: 1,
                                    ),
                                    background: Container(
                                        alignment: Alignment.topCenter,
                                        child: Column(
                                            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                            children: <Widget>[
                                                Row(
                                                    children: <Widget>[
                                                        Text(
                                                            '10.00 TL',
                                                            style: TextStyle(
                                                                    color: Colors.white,
                                                                    fontSize: 20.0,
                                                                    fontWeight: FontWeight.bold),
                                                        ),

                                                    ],
                                                    mainAxisAlignment: MainAxisAlignment.center,
                                                ),
                                                Container(
                                                    width: 0,
                                                    height: 0,
                                                )
                                            ],
                                        ),
                                    ),
                                    //background: ,
                                ),
                            ),
                            SliverPersistentHeader(
                                pinned: true,
                                delegate: _SliverAppBarDelegate(
                                    TabBar(
                                        tabs: [
                                            Tab(
                                                child: Text(
                                                    "Tab1",
                                                    style: TextStyle(
                                                            color: Colors.black,
                                                            fontWeight: FontWeight.bold),
                                                ),
                                            ),
                                            Tab(
                                                child: Text(
                                                    "Tab2",
                                                    style: TextStyle(
                                                            color: Colors.black,
                                                            fontWeight: FontWeight.bold),
                                                ),
                                            ),
                                        ],
                                    ),
                                ),
                            ),
                        ];
                    },

                    body:TabBarView(
                            //controller: _tabController,
                            children: [
                                CardList('one'),
                                CardList('two'),
                    ]),
                ),
            ),

        );

    }
}

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
    _SliverAppBarDelegate(this._tabBar);

    final TabBar _tabBar;

    @override
    double get minExtent => _tabBar.preferredSize.height;
    @override
    double get maxExtent => _tabBar.preferredSize.height;

    @override
    Widget build(
            BuildContext context, double shrinkOffset, bool overlapsContent) {
        return new Container(
            color: Colors.white,
            child: _tabBar,
        );
    }

    @override
    bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
        return false;
    }
}




class CardList extends StatelessWidget {
    final String listKey;

    CardList(this.listKey);

    @override
    Widget build(BuildContext context) {
        return Container(
            child: ListView.builder(
                    key: PageStorageKey<String>(listKey),
                    scrollDirection: Axis.vertical,
                    shrinkWrap: true,
                    itemCount: 20,
                    //itemExtent: 1.0,
                    itemBuilder: (context, index){
                        return new ListTile(
                            title: new Text("Item $index"),
                        );
                    }),
        );
    }
}