【问题标题】:Switch horizontal tabs on vertical scroll flutter在垂直滚动颤动上切换水平选项卡
【发布时间】:2021-09-12 16:12:57
【问题描述】:

如何在垂直滚动上切换选项卡,如上所示。最好的方法是什么?单击某个选项卡后,控制权应转移到选定的选项卡内容。我试图在谷歌上找到解决方案,但徒劳无功。

目前我的代码看起来像这样,但我知道不是这样。

class SingleRestView extends StatefulWidget {
  Restaurant singleRestaurant;
  SingleRestView({@required this.singleRestaurant});
  @override
  _SingleRestViewState createState() => _SingleRestViewState();
}

class _SingleRestViewState extends State<SingleRestView>
    with SingleTickerProviderStateMixin {
  var _tabController;

  @override
  void initState() {
    super.initState();

    _tabController = TabController(length: 3, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    var tabBar = TabBar(
      controller: _tabController,
      //This property will allow your tabs to be horizontally scrollable
      isScrollable: true,
      indicatorColor: Colors.black,
      labelColor: Colors.black,
      tabs: [
       Text("Tab 1"),
       Text("Tab 2"),
       Text("Tab 2"),
      ],
    );

    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (context, isScrolled) => [
          SliverAppBar(
            expandedHeight: 300,
            pinned: true,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('Title'),
              //Without this padding the title appears behind the tabs.
              //This is the whole reason why the tabBar is in a local variable, to
              //be able to use its height here.
              titlePadding: EdgeInsetsDirectional.only(
                  start: 72, bottom: tabBar.preferredSize.height + 16),
              // background:
            ),
            // I did this this way to have a white bottom bar like in your photo,
            // however, you could just pass the tabBar. The background image would
            //be behind it.
            bottom: PreferredSize(
              child: Container(
                //This will keep your tabs centered if you have not enough to fill
                //the display's width
                alignment: Alignment.center,
                width: double.infinity,
                color: Colors.white,
                child: tabBar,
              ),
              preferredSize: Size(double.infinity, tabBar.preferredSize.height),
            ),
          ),
        ],
        body: TabBarView(
          controller: _tabController,
          children: <Widget>[
           Container(height: 50,width: 100,color: Colors.red,),
           Container(height: 50,width: 100,color: Colors.blue,),
           Container(height: 50,width: 100,color: Colors.green,),
          ],
        ),
      ),
    );
  }
}

Video of what i want to achieve

【问题讨论】:

  • 嗨 Faizan,我列出了一些可能的选项,还附上了一些进一步的参考资料供阅读,我建议你一定要检查一下。谢谢你的问题:)

标签: flutter dart scroll scrollview


【解决方案1】:

nestedScrollController 有一个名为 offset 的属性,它将为您提供当前偏移量。

nestedScrollController.offset

但请记住,不同设备的屏幕尺寸可能不同。所以只使用偏移量不会有帮助。


1.使用 MediaQuery 的朴素选项

使用MediaQuery,您可以了解设备的高度,然后您可以根据偏移量和设备高度之间的比较全局更改tab_index。您可以使用一些阈值,然后水平tab_index 发生变化。设置适当的偏移值可能是一项艰巨的工作!

double new_height = MediaQuery.of(context).size.height;

if(new_height/2<=offset)
{
//change my tab_index to 2
}

2。在控制器中使用监听器

结合侦听器和偏移量

 _TabController.addListener(() {
    if (_controller.position.atEdge) {
      if (_controller.position.pixels == 0) {
        // You're at the top so tab_index=1 
      }

      //At the bottom of screen

      if(_controller.offset>=_controller.position.maxScrollExtent)
      {
         //set your tab_index
      }

      //middle of screen multiply by 0.5
      
      if(_controller.offset>=_controller.position.maxScrollExtent*0.5)
      {
         //set your tab_index
      } 
      
     //3/4 of screen multiply by 0.75
     
     if(_controller.offset>=_controller.position.maxScrollExtent*0.75)
      {
         //set your tab_index
      } 

    }

进一步阅读 -

  1. https://medium.com/@diegoveloper/flutter-lets-know-the-scrollcontroller-and-scrollnotification-652b2685a4ac
  2. Scroll Position Class
  3. How to check if scroll position is at top or bottom in ListView?

【讨论】:

    【解决方案2】:

    也许你可以尝试使用这个插件 => https://pub.dev/packages/vertical_scrollable_tabview/score

    import 'package:vertical_scrollable_tabview/vertical_scrollable_tabview.dart';
    
    // Required it
    TabBar(
        onTap: (index) {
            VerticalScrollableTabBarStatus.setIndex(index); <- Required 
        },
    )
    
    and
    
    VerticalScrollableTabView(
        tabController: tabController,                             <- Required TabBarController
        listItemData: data,                                       <- Required List<dynamic>
        eachItemChild: (object,index){
            return CategorySection(category: object as Category); <- Object and index
        },
        verticalScrollPosition: VerticalScrollPosition.begin,
    ),
    

    我觉得这个插件可以解决。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-26
    • 1970-01-01
    • 2021-11-13
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多