如何在 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
进行包装,创建一个 callBack
或 stateManagement
来保存索引。
结果
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