首页 > 解决方案 > 当用户在颤动中向下滚动 tab1 时,如何防止在 tab2 上自动向下滚动?

问题描述

SliverAppBar我使用、SliverPersistentHeader和. 创建TabView了一个屏幕ListView

如果我在 tab1 中向下滚动,tab2 会自动向下滚动。因此,如果我切换到 tab2,则列表不是从第一项开始。我怎样才能防止这种情况?

我创建了简单的演示应用程序来演示这个问题,你可以看看这个gist

画面初始状态: 1

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

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

标签: flutterflutter-layoutflutter-sliver

解决方案


我已经用 PageStorageKey修改了你的要点。请参见下面的工作示例:

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"),
                        );
                    }),
        );
    }
}

推荐阅读