【问题标题】:How can I set a scrollable TabBar in Flutter?如何在 Flutter 中设置可滚动的 TabBar?
【发布时间】:2021-08-20 20:09:10
【问题描述】:

我的 TabBar 出现问题,我希望它可以滚动(通过手势左右滑动)。

但它不起作用,我必须单击子类别名称才能查看它,但我希望它向右滚动以转到下一个子类别。

我在 TabBar 小部件中设置了 isScrollable: true,但仍然是同样的问题。

如果有什么建议我在这里谢谢你:)

1st screen

2nd screen

class CategoryScreen extends StatefulWidget {
  final CategoryModel categoryModel;
  CategoryScreen({@required this.categoryModel});

  @override
  _CategoryScreenState createState() => _CategoryScreenState();
}

class _CategoryScreenState extends State<CategoryScreen>
    with TickerProviderStateMixin {
  int _tabIndex = 0;

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

    Provider.of<CategoryProvider>(context, listen: false)
        .getSubCategoryList(context, widget.categoryModel.id.toString());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: ResponsiveHelper.isDesktop(context)
          ? PreferredSize(
              child: MainAppBar(), preferredSize: Size.fromHeight(80))
          : null,
      body: Consumer<CategoryProvider>(
        builder: (context, category, child) {
          return category.subCategoryList != null
              ? Center(
                  child: Scrollbar(
                    child: Container(
                      width: 1170,
                      child: CustomScrollView(
                        physics: BouncingScrollPhysics(),
                        slivers: [
                          SliverAppBar(
                            expandedHeight: 200,
                            toolbarHeight:
                                50 + MediaQuery.of(context).padding.top,
                            pinned: true,
                            floating: false,
                            backgroundColor: Theme.of(context).primaryColor,
                            leading: IconButton(
                                icon: Icon(Icons.chevron_left,
                                    color: ColorResources.COLOR_WHITE),
                                onPressed: () => Navigator.pop(context)),
                            flexibleSpace: FlexibleSpaceBar(
                              title: Text(widget.categoryModel.name,
                                  style: rubikMedium.copyWith(
                                      fontSize: Dimensions.FONT_SIZE_LARGE,
                                      color: Colors.white)),
                              titlePadding: EdgeInsets.only(
                                bottom: 54 +
                                    (MediaQuery.of(context).padding.top / 2),
                                left: 50,
                                right: 50,
                              ),
                              background: Container(
                                margin: EdgeInsets.only(bottom: 50),
                                child: FadeInImage.assetNetwork(
                                  placeholder: Images.placeholder_rectangle,
                                  image:
                                      '${Provider.of<SplashProvider>(context, listen: false).baseUrls.categoryImageUrl}/${widget.categoryModel.image}',
                                  fit: BoxFit.cover,
                                ),
                              ),
                            ),
                            bottom: PreferredSize(
                              preferredSize: Size.fromHeight(30.0),
                              child: Container(
                                width: MediaQuery.of(context).size.width,
                                color: Theme.of(context).accentColor,
                                **child: TabBar(
                                  controller: TabController(
                                      initialIndex: _tabIndex,
                                      length:
                                          category.subCategoryList.length + 1,
                                      vsync: this),
                                  isScrollable: true,
                                  unselectedLabelColor:
                                      ColorResources.getGreyColor(context),
                                  indicatorWeight: 3,
                                  indicatorSize: TabBarIndicatorSize.label,
                                  indicatorColor:
                                      Theme.of(context).primaryColor,
                                  labelColor: Theme.of(context)
                                      .textTheme
                                      .bodyText1
                                      .color,
                                  tabs: _tabs(category),
                                  onTap: (int index) {
                                    _tabIndex = index;
                                    if (index == 0) {
                                      category.getCategoryProductList(context,
                                          widget.categoryModel.id.toString());
                                    } else {
                                      category.getCategoryProductList(
                                          context,
                                          category.subCategoryList[index - 1].id
                                              .toString());
                                    }
                                  },
                                ),
                              ),
                            ),
                          ),**
                          SliverToBoxAdapter(
                            child: category.categoryProductList != null
                                ? category.categoryProductList.length > 0
                                    ? GridView.builder(
                                        gridDelegate:
                                            SliverGridDelegateWithFixedCrossAxisCount(
                                                crossAxisSpacing: 5,
                                                mainAxisSpacing: 5,
                                                childAspectRatio: 4,
                                                crossAxisCount: ResponsiveHelper
                                                        .isDesktop(context)
                                                    ? 3
                                                    : ResponsiveHelper.isTab(
                                                            context)
                                                        ? 2
                                                        : 1),
                                        itemCount:
                                            category.categoryProductList.length,
                                        shrinkWrap: true,
                                        physics: NeverScrollableScrollPhysics(),
                                        padding: EdgeInsets.all(
                                            Dimensions.PADDING_SIZE_SMALL),
                                        itemBuilder: (context, index) {
                                          return ProductWidget(
                                              product: category
                                                  .categoryProductList[index]);
                                        },
                                      )
                                    : NoDataScreen()
                                : GridView.builder(
                                    shrinkWrap: true,
                                    itemCount: 10,
                                    physics: NeverScrollableScrollPhysics(),
                                    padding: EdgeInsets.all(
                                        Dimensions.PADDING_SIZE_SMALL),
                                    gridDelegate:
                                        SliverGridDelegateWithFixedCrossAxisCount(
                                      crossAxisSpacing: 5,
                                      mainAxisSpacing: 5,
                                      childAspectRatio: 4,
                                      crossAxisCount:
                                          ResponsiveHelper.isDesktop(context)
                                              ? 3
                                              : ResponsiveHelper.isTab(context)
                                                  ? 2
                                                  : 1,
                                    ),
                                    itemBuilder: (context, index) {
                                      return ProductShimmer(
                                          isEnabled:
                                              category.categoryProductList ==
                                                  null);
                                    },
                                  ),
                          ),
                        ],
                      ),
                    ),
                  ),
                )
              : Center(
                  child: CircularProgressIndicator(
                      valueColor: AlwaysStoppedAnimation<Color>(
                          Theme.of(context).primaryColor)));
        },
      ),
    );
  }

  List<Tab> _tabs(CategoryProvider category) {
    List<Tab> tabList = [];
    tabList.add(Tab(text: 'Tout'));
    category.subCategoryList
        .forEach((subCategory) => tabList.add(Tab(text: subCategory.name)));
    return tabList;
  }
}

【问题讨论】:

  • 您需要将正文设为TabBarView,并将页面列表提供给children 参数。
  • 我试过这样但没有任何建议?谢谢 :) SliverToBoxAdapter( child: TabBarView( controller: TabController( initialIndex: 0, length: category.categoryProductList.length, vsync: this), children: [ category.categoryProductList != null ? category.categoryProductList.length > 0 ? GridView .builder(

标签: flutter dart gesture tabbar scrollable


【解决方案1】:

您需要使用NestedScrollView 才能使用SliverTabBar

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.dark(),
      home: SliverTabExample(),
    ),
  );
}

class SliverTabExample extends StatefulWidget {
  const SliverTabExample({Key? key}) : super(key: key);

  @override
  _SliverTabExampleState createState() => _SliverTabExampleState();
}

class _SliverTabExampleState extends State<SliverTabExample>
    with SingleTickerProviderStateMixin {
  final _tabs = List.generate(10, (index) => 'Tab#${index + 1}');

  late final TabController _tabCont;
  @override
  void initState() {
    _tabCont = TabController(length: 10, vsync: this);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (_, __) {
          return [
            SliverAppBar(
              expandedHeight: 200,
              pinned: true,
              floating: false,
              title: Text('TabBar Example'),
              centerTitle: true,
              bottom: TabBar(
                controller: _tabCont,
                isScrollable: true,
                tabs: [
                  ..._tabs.map(
                    (label) => Tab(
                      child: Text(label),
                    ),
                  ),
                ],
              ),
            ),
          ];
        },
        body: TabBarView(
          controller: _tabCont,
          children: [
            ..._tabs.map(
              (label) => SamplePage(
                label: label,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class SamplePage extends StatelessWidget {
  const SamplePage({Key? key, required this.label}) : super(key: key);
  final String label;
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(child: Text('Page of $label')),
    );
  }
}

【讨论】:

    猜你喜欢
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2019-08-06
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    相关资源
    最近更新 更多