Dart 我想在单击父选项卡后创建动态子选项卡和子选项卡视图

Dart 我想在单击父选项卡后创建动态子选项卡和子选项卡视图,dart,flutter,Dart,Flutter,想要克隆Flatter中的playstore首页appbar滚动功能。我正在尝试制作一个屏幕,其中包含SliveAppBar底部属性下的静态选项卡。每当单击任何父静态选项卡时,我都需要创建动态选项卡和TabbarView。我做得很成功,但我面临一些问题 当我单击任何父选项卡时,我会尝试初始化tabController,但currentIndex与前一个父选项卡中的一样 每个选项卡主体必须保存其滚动位置 这是我的屏幕代码 class DynamicTabContent { IconData

想要克隆Flatter中的playstore首页appbar滚动功能。我正在尝试制作一个屏幕,其中包含SliveAppBar底部属性下的静态选项卡。每当单击任何父静态选项卡时,我都需要创建动态选项卡和TabbarView。我做得很成功,但我面临一些问题

  • 当我单击任何父选项卡时,我会尝试初始化tabController,但currentIndex与前一个父选项卡中的一样
  • 每个选项卡主体必须保存其滚动位置
  • 这是我的屏幕代码

    class DynamicTabContent {
       IconData icon;
       String tooTip;
    
       DynamicTabContent.name(this.icon, this.tooTip);
    }
    
    int currentTabBlue = 0;
    
    class TestAppHomePage extends StatefulWidget {
     @override
      TestAppHomePageState createState() => new TestAppHomePageState();
    }
    
    class TestAppHomePageState extends State<TestAppHomePage>
    with TickerProviderStateMixin {
     List<DynamicTabContent> myList = new List();
     ScrollController _scrollController = new ScrollController();
     TabController _tabControllerBlue;
     TabController _tabController;
    
     handleTabChange() {
        currentTabBlue = _tabControllerBlue.index;
        print("CurrentTab = " + currentTabBlue.toString());
        if (_tabControllerBlue.index == 0) {
          setState(() {
            myList.clear();
            myList.add(new DynamicTabContent.name(Icons.favorite, "Favorited"));
            myList
            .add(new DynamicTabContent.name(Icons.local_pizza, "local pizza"));
    
            this._tabController = new TabController(initialIndex: 0, length: 15, vsync: this);
          });
        } else if (_tabControllerBlue.index == 1) {
          setState(() {
            myList.clear();
            myList.add(new DynamicTabContent.name(Icons.favorite, "Favorited"));
            myList
            .add(new DynamicTabContent.name(Icons.local_pizza, "local pizza"));
            myList
            .add(new DynamicTabContent.name(Icons.local_pizza, "local pizza"));
    
            this._tabController = new TabController(initialIndex: 0, length: 15, vsync: this);
          });
        } else if (_tabControllerBlue.index == 2) {
          setState(() {
            myList.clear();
            myList.add(new DynamicTabContent.name(Icons.favorite, "Favorited"));
            myList.add(new DynamicTabContent.name(Icons.favorite, "Favorited"));
            myList
            .add(new DynamicTabContent.name(Icons.local_pizza, "local pizza"));
            myList
            .add(new DynamicTabContent.name(Icons.local_pizza, "local pizza"));
            myList
            .add(new DynamicTabContent.name(Icons.local_pizza, "local pizza"));
    
            this._tabController = new TabController(initialIndex: 0, length: 15, vsync: this);
          });
        }
      }
    
      @override
      void initState() {
        print("initState = TestAppHomePage");
    
        myList.add(new DynamicTabContent.name(Icons.favorite, "Favorited"));
        myList.add(new DynamicTabContent.name(Icons.local_pizza, "local pizza"));
    
        _tabControllerBlue =
        new TabController(initialIndex: 0, length: 3, vsync: this);
        _tabControllerBlue.addListener(handleTabChange);
        _tabController =
        new TabController(initialIndex: 0, length: myList.length, vsync: this);
      }
    
      @override
      void dispose() {
        print("dispose");
    //    _tabController.removeListener(handleTabChange);
    //    _tabController.dispose();
        super.dispose();
      }
    
      Future<void> executeAfterBuild() async {
        print("Build: Called Back");
      }
    
      @override
      Widget build(BuildContext context) {
        executeAfterBuild();
        return new Scaffold(
          body: new NestedScrollView(
            controller: _scrollController,
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              return <Widget>[
                SliverAppBar(
                  leading: IconButton(
                    icon: Icon(
                      Icons.arrow_back,
                      color: Colors.white,
                    ),
                    onPressed: null,
                  ),
                  title: Text('Kitchen'),
                  floating: true,
                  pinned: true,
                  bottom: TabBar(
                    controller: _tabControllerBlue,
                    tabs: [
                      Tab(icon: Icon(Icons.lightbulb_outline), text: "Tab 1"),
                      Tab(icon: Icon(Icons.lightbulb_outline), text: "Tab 2"),
                      Tab(icon: Icon(Icons.lightbulb_outline), text: "Tab 3"),
                    ],
                  ),
                ),
                new SliverPersistentHeader(
                  pinned: true,
                  delegate: TestTabBarDelegate(controller: _tabController),
                ),
              ];
            },
            body: new TestHomePageBody(
              tabController: _tabController,
              scrollController: _scrollController,
              myList: myList,
            ),
          ),
        );
      }
    }
    
    class TestHomePageBody extends StatefulWidget {
      TestHomePageBody({this.tabController, this.scrollController, this.myList});
    
      final TabController tabController;
      final ScrollController scrollController;
      final List<DynamicTabContent> myList;
    
      State<StatefulWidget> createState() {
        return TestHomePageBodyState();
      }
    }
    
    class TestHomePageBodyState extends State<TestHomePageBody> {
      Key _key = new PageStorageKey({});
      bool _innerListIsScrolled = false;
    
      void _updateScrollPosition() {
    
        if (!_innerListIsScrolled &&
            widget.scrollController.position.extentAfter == 0.0) {
          setState(() {
            _innerListIsScrolled = true;
           print("_innerListIsScrolled = true");
          });
        } else if (_innerListIsScrolled &&
            widget.scrollController.position.extentAfter > 0.0) {
          setState(() {
            _innerListIsScrolled = false;
            print("_innerListIsScrolled = false");
            // Reset scroll positions of the TabBarView pages
            _key = new PageStorageKey({});
          });
        }
      }
    
      @override
      void initState() {
        widget.scrollController.addListener(_updateScrollPosition);
        print("initState = TestHomePageBodyState");
        super.initState();
      }
    
      @override
      void dispose() {
        widget.scrollController.removeListener(_updateScrollPosition);
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return new TabBarView(
          controller: widget.tabController,
          key: _key,
          children: widget.myList.isEmpty
              ? <Widget>[]
              : widget.myList.map(
                  (dynamicContent) {
                    return new Card(
                      child: new Column(
                        children: <Widget>[
                          new Container(
                            height: 450.0,
                            width: 300.0,
                            child: new IconButton(
                              icon: new Icon(dynamicContent.icon, size: 100.0),
                              tooltip: dynamicContent.tooTip,
                              onPressed: null,
                            ),
                          ),
                          Text(dynamicContent.tooTip),
                        ],
                      ),
                    );
                  },
                ).toList(),
        );
      }
    }
    
    class TestTabBarDelegate extends SliverPersistentHeaderDelegate {
      TestTabBarDelegate({this.controller});
    
      final TabController controller;
    
      @override
      double get minExtent => kToolbarHeight;
    
      @override
      double get maxExtent => kToolbarHeight;
    
      @override
      Widget build(
          BuildContext context, double shrinkOffset, bool overlapsContent) {
        return new Container(
          color: Theme.of(context).cardColor,
          height: kToolbarHeight,
          child: new TabBar(
            controller: controller,
            isScrollable: true,
            labelColor: Theme.of(context).accentColor,
            indicatorSize: TabBarIndicatorSize.label,
            key: new PageStorageKey<Type>(TabBar),
            indicatorColor: Theme.of(context).accentColor,
            tabs: List<Widget>.generate(controller.length, (int index) {
              print(controller.length);
              return new Tab(text: "Excluded Discounted Deals");
            }),
          ),
        );
      }
    
      @override
      bool shouldRebuild(covariant TestTabBarDelegate oldDelegate) {
        return oldDelegate.controller != controller;
      }
    }
    
    类动态内容{
    Iconda图标;
    线头;
    DynamicTabContent.name(this.icon、this.tooTip);
    }
    int currentTabBlue=0;
    类TestAppHomePage扩展StatefulWidget{
    @凌驾
    TestAppHomePageState createState()=>new TestAppHomePageState();
    }
    类TestAppHomePageState扩展了状态
    使用TickerProviderStateMixin{
    List myList=新列表();
    ScrollController_ScrollController=新的ScrollController();
    TabController\u tabControllerBlue;
    TabController\u TabController;
    handleTabChange(){
    currentTabBlue=\u tabControllerBlue.index;
    打印(“CurrentTab=“+currentTabBlue.toString());
    if(_tabControllerBlue.index==0){
    设置状态(){
    myList.clear();
    添加(新的DynamicTabContent.name(Icons.favorite,“Favorited”);
    迈利斯特
    .add(新的DynamicTabContent.name(Icons.local_pizza,“local pizza”);
    this.\tabController=newtabcontroller(初始索引:0,长度:15,vsync:this);
    });
    }else if(_tabControllerBlue.index==1){
    设置状态(){
    myList.clear();
    添加(新的DynamicTabContent.name(Icons.favorite,“Favorited”);
    迈利斯特
    .add(新的DynamicTabContent.name(Icons.local_pizza,“local pizza”);
    迈利斯特
    .add(新的DynamicTabContent.name(Icons.local_pizza,“local pizza”);
    this.\tabController=newtabcontroller(初始索引:0,长度:15,vsync:this);
    });
    }else if(_tabControllerBlue.index==2){
    设置状态(){
    myList.clear();
    添加(新的DynamicTabContent.name(Icons.favorite,“Favorited”);
    添加(新的DynamicTabContent.name(Icons.favorite,“Favorited”);
    迈利斯特
    .add(新的DynamicTabContent.name(Icons.local_pizza,“local pizza”);
    迈利斯特
    .add(新的DynamicTabContent.name(Icons.local_pizza,“local pizza”);
    迈利斯特
    .add(新的DynamicTabContent.name(Icons.local_pizza,“local pizza”);
    this.\tabController=newtabcontroller(初始索引:0,长度:15,vsync:this);
    });
    }
    }
    @凌驾
    void initState(){
    打印(“initState=TestAppHomePage”);
    添加(新的DynamicTabContent.name(Icons.favorite,“Favorited”);
    添加(新的DynamicTabContent.name(Icons.local_pizza,“local pizza”);
    _tabControllerBlue=
    新的TabController(initialIndex:0,length:3,vsync:this);
    _tabControllerBlue.addListener(handleTabChange);
    _选项卡控制器=
    新的TabController(initialIndex:0,length:myList.length,vsync:this);
    }
    @凌驾
    无效处置(){
    打印(“处置”);
    //_tabController.removeListener(handleTabChange);
    //tabController.dispose();
    super.dispose();
    }
    Future executeAfterBuild()异步{
    打印(“构建:回调”);
    }
    @凌驾
    小部件构建(构建上下文){
    executeAfterBuild();
    归还新脚手架(
    正文:新嵌套滚动视图(
    控制器:\ u滚动控制器,
    headerSliverBuilder:(BuildContext上下文,boolInnerBoxIsCrolled){
    返回[
    滑杆(
    领先:IconButton(
    图标:图标(
    Icons.arrow_back,
    颜色:颜色,白色,
    ),
    onPressed:null,
    ),
    标题:文本(“厨房”),
    浮动:是的,
    对,,
    底部:选项卡栏(
    控制器:\选项卡控制器蓝色,
    选项卡:[
    选项卡(图标:图标(图标、灯泡轮廓),文本:“选项卡1”),
    选项卡(图标:图标(图标。灯泡轮廓),文本:“选项卡2”),
    选项卡(图标:图标(图标、灯泡轮廓),文本:“选项卡3”),
    ],
    ),
    ),
    新型滑片导板(
    对,,
    代表:TestTabBarDelegate(控制器:_TabbController),
    ),
    ];
    },
    正文:新的TestHomePageBody(
    tabController:\u tabController,
    scrollController:\u scrollController,
    myList:myList,
    ),
    ),
    );
    }
    }
    类TestHomePageBody扩展StatefulWidget{
    TestHomePageBody({this.tabController,this.scrollController,this.myList});
    最终TabController TabController;
    最终滚动控制器滚动控制器;
    最后名单;
    状态createState(){
    返回TestHomePageBodyState();
    }
    }
    类TestHomePageBodyState扩展了状态{
    Key _Key=new PageStorageKey({});
    bool\u innerlistiscrowled=false;
    void _updateScrollPosition(){
    如果(!\u内部列表为crowled&&
    widget.scrollController.position.extentAfter==0.0){
    设置状态(){
    _innerlistiscrowled=true;
    打印(“_innerlistiscrowled=true”);
    });
    }否则,如果(_innerlistiscrowled&&
    widget.scrollController.position.extentAfter>0.0){
    设置状态(){
    _innerlistiscrowled=false;
    打印(“_innerlistiscrowled=false”);
    //重置TabBarView页面的滚动位置
    _key=new PageStorageKey({});
    });
    }
    }
    @凌驾
    void initState(){
    widget.scrollController.addListener(_updateScrollPosition);
    打印(“initState=TestHomePageBodyState”);
    super.initState();
    }
    @凌驾
    无效处置(){
    widget.scrollController.removeListener(\u update
    
    // Reading state:
        var tabInternalIndex = PageStorage.of(context).readState(context, identifier: ValueKey('tab3'));
        _currentTab = tabInternalIndex == null ? _currentTab : tabInternalIndex;
    
    // Writing State
    onTap: (int index) {
      setState(() {
        _currentTab = index;
        PageStorage.of(context).writeState(context, index,
            identifier: ValueKey('tab3'));
      });
    }
    
    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return DefaultTabController(
          length: 3,
          initialIndex: 1,
          child: Scaffold(
            appBar: AppBar(
              bottom: TabBar(
                tabs: [
                  Tab(icon: Icon(Icons.mail)),
                  Tab(icon: Icon(Icons.contacts)),
                  Tab(icon: Icon(Icons.info)),
                ],
              ),
              title: Text('Sample tabs'),
            ),
            body: TabBarView(children: <Widget>[
              SubTabs1(),
              SubTabs2(),
              SubTabs3()
            ]),
          ),
        );
      }
    }
    
    class SubTabs1 extends StatefulWidget {
      @override
      _SubTabs1State createState() => _SubTabs1State();
    }
    
    class _SubTabs1State extends State<SubTabs1> {
      int _currentTab = 0;
    
      @override
      Widget build(BuildContext context) {
        var tabInternalIndex = PageStorage.of(context)
            .readState(context, identifier: ValueKey('tab1'));
        _currentTab = tabInternalIndex == null ? _currentTab : tabInternalIndex;
        return DefaultTabController(
            initialIndex: _currentTab,
            length: 3,
            child: Scaffold(
                appBar: AppBar(
                  bottom: TabBar(
                    onTap: (int index) {
                      setState(() {
                        _currentTab = index;
                        PageStorage.of(context).writeState(context, index,
                            identifier: ValueKey('tab1'));
                      });
                    },
                    tabs: [
                      Tab(icon: Icon(Icons.delete)),
                      Tab(icon: Icon(Icons.delete_forever)),
                      Tab(icon: Icon(Icons.delete_outline)),
                    ],
                  ),
                ),
                body: TabBarView(
                  children: <Widget>[
                    Container(
                      color: Colors.green[100],
                      child: Text('Child 5'),
                    ),
                    Container(
                      color: Colors.green[300],
                      child: Text('Child 6'),
                    ),
                    Container(
                      color: Colors.green[600],
                      child: Text('Child 7'),
                    )
                  ],
                )));
      }
    }
    
    class SubTabs2 extends StatefulWidget {
      @override
      _SubTabs2State createState() => _SubTabs2State();
    }
    
    class _SubTabs2State extends State<SubTabs2> {
      int _currentTab = 0;
      @override
      Widget build(BuildContext context) {
        var tabInternalIndex = PageStorage.of(context)
            .readState(context, identifier: ValueKey('tab2'));
        _currentTab = tabInternalIndex == null ? _currentTab : tabInternalIndex;
        return DefaultTabController(
            initialIndex: _currentTab,
            length: 3,
            child: Scaffold(
                appBar: AppBar(
                  bottom: TabBar(
                    onTap: (int index) {
                      setState(() {
                        _currentTab = index;
                        PageStorage.of(context).writeState(context, index,
                            identifier: ValueKey('tab2'));
                      });
                    },
                    tabs: [
                      Tab(icon: Icon(Icons.alarm_add)),
                      Tab(icon: Icon(Icons.alarm_off)),
                      Tab(icon: Icon(Icons.alarm_on)),
                    ],
                  ),
                ),
                body: TabBarView(
                  children: <Widget>[
                    Container(
                      color: Colors.yellow[100],
                      child: Text('Child 5'),
                    ),
                    Container(
                      color: Colors.yellow[300],
                      child: Text('Child 6'),
                    ),
                    Container(
                      color: Colors.yellow[600],
                      child: Text('Child 7'),
                    )
                  ],
                )));
      }
    }
    
    class SubTabs3 extends StatefulWidget {
      @override
      _SubTabs3State createState() => _SubTabs3State();
    }
    
    class _SubTabs3State extends State<SubTabs3> {
      int _currentTab = 0;
    
      @override
      Widget build(BuildContext context) {
        // Reading state:
        var tabInternalIndex = PageStorage.of(context).readState(context, identifier: ValueKey('tab3'));
        _currentTab = tabInternalIndex == null ? _currentTab : tabInternalIndex;
        return DefaultTabController(
            initialIndex: _currentTab,
            length: 3,
            child: Scaffold(
                appBar: AppBar(
                  bottom: TabBar(
                    onTap: (int index) {
                      setState(() {
                        _currentTab = index;
                        PageStorage.of(context).writeState(context, index,
                            identifier: ValueKey('tab3'));
                      });
                    },
                    tabs: [
                      Tab(icon: Icon(Icons.ac_unit)),
                      Tab(icon: Icon(Icons.accessible)),
                      Tab(icon: Icon(Icons.airport_shuttle)),
                    ],
                  ),
                ),
                body: TabBarView(
                  children: <Widget>[
                    Container(
                      color: Colors.pink[100],
                      child: Text('Child 1'),
                    ),
                    Container(
                      color: Colors.pink[300],
                      child: Text('Child 2'),
                    ),
                    Container(
                      color: Colors.pink[600],
                      child: Text('Child 3'),
                    )
                  ],
                )));
      }
    }