如何在 Flutter 中创建像这样的自定义可滑动标签栏?

Posted

技术标签:

【中文标题】如何在 Flutter 中创建像这样的自定义可滑动标签栏?【英文标题】:How can I create a custom swipable tab bar like this in Flutter? 【发布时间】:2021-10-16 02:43:55 【问题描述】:

我想创建一个像上面那样的标签栏,它可以用动画滑动。我尝试使用 Flutter 中的默认选项卡栏小部件执行此操作,但失败了。如何使此标签栏可通过动画滑动?

将选中的选项卡动画从“朋友”选项卡下拉到“家庭”选项卡背后的逻辑是什么?

我从 GestureDetector 小部件中找到了 onHorizontalDrag 属性来进行滑动,但仍然无法用动画切换标签。

如果有人可以帮助我,那就太好了。

【问题讨论】:

你能添加你的代码sn-p吗?你试过PageView吗? 不,我没有尝试 PageView。就算是浏览量,也会有动画吗? 是的,您可以在那里找到物理,也可以使用PageView.builder 中的itemBuilder 进行更多自定义。 你能分享一个代码sn-p吗?对我有很大的帮助,兄弟。 我想我会更喜欢IndexedStack,请给我一些时间。 【参考方案1】:

这是使用 PageView 和 customAppBar 制作的。但是,如果您想在 tabBaritem 上使用 clickEvent,请使用 GestureDetector 进行包装,创建一个 callBackstateManagement 来保存索引。

结果

MainWidget


class BU extends StatefulWidget 
  BU(Key? key) : super(key: key);

  @override
  _BUState createState() => _BUState();


class _BUState extends State<BU> 
  int _selectedIndex = 0;

  final PageController controller = PageController(initialPage: 0);

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

    widgets = [
      ...List.generate(
        5,
        (index) => Container(
          alignment: Alignment.center,
          color: index.isEven ? Colors.cyanAccent : Colors.deepPurple,
          child: Text(
            "Item $index",
            style: TextStyle(fontSize: 44),
          ),
        ),
      )
    ];

    controller.addListener(() 
      if (controller.hasClients) 
        setState(() 
          /// you can ceil foor
          _selectedIndex = controller.page!.toInt();
        );
      
    );
  

  @override
  void dispose() 
    controller.dispose();
    super.dispose();
  

  late List<Widget> widgets;
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Column(
        children: [
          AppBar(
            selectedItem: _selectedIndex,
          ),
          Expanded(
            child: Container(
                width: double.infinity,
                child: PageView(
                  controller: controller,
                  children: [...widgets],
                )),
          )
        ],
      ),
    );
  

标签栏


class AppBar extends StatelessWidget 
  final int selectedItem;

  const AppBar(
    Key? key,
    required this.selectedItem,
  ) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return Container(
      padding: EdgeInsets.all(8),
      color: Colors.white,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              TabItemChip(
                isSelected: selectedItem == 0,
                text: "Profile",
              ),
              TabItemChip(
                isSelected: selectedItem == 1,
                text: "About",
              ),
              TabItemChip(
                isSelected: selectedItem == 2,
                text: "Friends",
              ),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              TabItemChip(
                isSelected: selectedItem == 3,
                text: "Family",
              ),
              TabItemChip(
                isSelected: selectedItem == 4,
                text: "Settings",
              ),
            ],
          )
        ],
      ),
    );
  


TabBarItemChip

class TabItemChip extends StatelessWidget 
  final bool isSelected;
  final String text;
  const TabItemChip(
    Key? key,
    required this.text,
    required this.isSelected,
  ) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return AnimatedContainer(
      duration: Duration(milliseconds: 400),
      height: 40,
      width: 140,
      alignment: Alignment.center,
      decoration: BoxDecoration(
        color: isSelected ? Colors.cyanAccent.shade700 : Colors.white,
        borderRadius: BorderRadius.circular(12),
      ),
      child: Text(
        text,
        style: TextStyle(
          color: isSelected ? Colors.white : Colors.black,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  


【讨论】:

工作就像一个魅力,朋友。非常感谢! 然后接受这个作为答案,随时结束问题。

以上是关于如何在 Flutter 中创建像这样的自定义可滑动标签栏?的主要内容,如果未能解决你的问题,请参考以下文章

在 ios 中创建像 UiActionSheet 这样的自定义 uiView

Flutter:自定义单选按钮

如何在 Swift 中创建像指南针一样的“滑动视图”?

在原生android中创建像flutter一样的高度卡

如何在 Flutter 中创建像 Ajio 移动应用一样的加载器动画。下面是装载机的视频

如何在 android 中创建像 QuickPic 应用程序这样的裁剪工具?