如何创建与颤动中的小部件滚动同步的选项卡栏?

Jay*_*ado 5 nestedscrollview flutter flutter-layout

基本上我想在这里完成的是拥有一个水平类别列表(可以是 TabBar)和一个垂直类别列表,每个类别中都有项目列表。

当您单击某个类别时,它应该滚动到类别垂直列表中的某个位置。当您滚动垂直列表时,顶部的活动类别也应该更新当前的活动类别。

我在 FoodPanda 应用程序中看到过此功能,但无法复制它。

关于如何实现此功能有什么建议吗?

这是用户界面的屏幕截图。 在此输入图像描述

chu*_*han 6

您可以复制粘贴运行下面的完整代码
您可以使用包https://pub.dev/packages/scrollable_list_tabview
代码片段

body: ScrollableListTabView(
        tabHeight: 48,
        bodyAnimationDuration: const Duration(milliseconds: 150),
        tabAnimationCurve: Curves.easeOut,
        tabAnimationDuration: const Duration(milliseconds: 200),
        tabs: [
          ScrollableListTab(
              tab: ListTab(
                  label: Text('Vegetables'),
                  icon: Icon(Icons.group),
                  showIconOnList: false),
              body: ListView.builder(
                shrinkWrap: true,
                physics: NeverScrollableScrollPhysics(),
                itemCount: 10,
                itemBuilder: (_, index) => ListTile(
                  leading: Container(
                    height: 40,
                    width: 40,
                    decoration: BoxDecoration(
                        shape: BoxShape.circle, color: Colors.grey),
                    alignment: Alignment.center,
                    child: Text(index.toString()),
                  ),
                  title: Text('Vegetables element $index'),
                ),
              )),
          ScrollableListTab(
              tab: ListTab(label: Text('Fruits'), icon: Icon(Icons.add)),
              body: ListView.builder(
                shrinkWrap: true,
                physics: NeverScrollableScrollPhysics(),
Run Code Online (Sandbox Code Playgroud)

工作演示

在此输入图像描述

完整代码

import 'package:flutter/material.dart';
import 'package:scrollable_list_tabview/scrollable_list_tabview.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter ScrollableListTabView Example'),
    );
  }
}

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 Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ScrollableListTabView(
        tabHeight: 48,
        bodyAnimationDuration: const Duration(milliseconds: 150),
        tabAnimationCurve: Curves.easeOut,
        tabAnimationDuration: const Duration(milliseconds: 200),
        tabs: [
          ScrollableListTab(
              tab: ListTab(
                  label: Text('Vegetables'),
                  icon: Icon(Icons.group),
                  showIconOnList: false),
              body: ListView.builder(
                shrinkWrap: true,
                physics: NeverScrollableScrollPhysics(),
                itemCount: 10,
                itemBuilder: (_, index) => ListTile(
                  leading: Container(
                    height: 40,
                    width: 40,
                    decoration: BoxDecoration(
                        shape: BoxShape.circle, color: Colors.grey),
                    alignment: Alignment.center,
                    child: Text(index.toString()),
                  ),
                  title: Text('Vegetables element $index'),
                ),
              )),
          ScrollableListTab(
              tab: ListTab(label: Text('Fruits'), icon: Icon(Icons.add)),
              body: ListView.builder(
                shrinkWrap: true,
                physics: NeverScrollableScrollPhysics(),
                itemCount: 10,
                itemBuilder: (_, index) => ListTile(
                  leading: Container(
                    height: 40,
                    width: 40,
                    decoration: BoxDecoration(
                        shape: BoxShape.circle, color: Colors.grey),
                    alignment: Alignment.center,
                    child: Text(index.toString()),
                  ),
                  title: Text('Fruits element $index'),
                ),
              )),
          ScrollableListTab(
              tab: ListTab(label: Text('Meat'), icon: Icon(Icons.group)),
              body: ListView.builder(
                shrinkWrap: true,
                physics: NeverScrollableScrollPhysics(),
                itemCount: 10,
                itemBuilder: (_, index) => ListTile(
                  leading: Container(
                    height: 40,
                    width: 40,
                    decoration: BoxDecoration(
                        shape: BoxShape.circle, color: Colors.grey),
                    alignment: Alignment.center,
                    child: Text(index.toString()),
                  ),
                  title: Text('Meat element $index'),
                ),
              )),
          ScrollableListTab(
              tab: ListTab(
                  label: Text('Herbs&Spices'), icon: Icon(Icons.subject)),
              body: GridView.builder(
                shrinkWrap: true,
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 2),
                physics: NeverScrollableScrollPhysics(),
                itemCount: 10,
                itemBuilder: (_, index) => Card(
                  child: Center(child: Text('Herbs&Spices element $index')),
                ),
              )),
          ScrollableListTab(
              tab: ListTab(
                  label: Text('Egg'),
                  icon: Icon(Icons.subject),
                  showIconOnList: true),
              body: GridView.builder(
                shrinkWrap: true,
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 2),
                physics: NeverScrollableScrollPhysics(),
                itemCount: 10,
                itemBuilder: (_, index) => Card(
                  child: Center(child: Text('Egg element $index')),
                ),
              )),
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)