🌟
TabViewにアニメーションを実装する!!
1.概要
NestedScrollViewでのタブの切り替え時にアニメーションを追加します。
DefaultTabControllerにはデフォルトでインジケーターが実装されていますが、今回はタブの背景がアニメーションするようにしてみます!!
実際に実装したリポジトリはこちらから確認できます!
2. 実装
class _TabBarDelegate extends SliverPersistentHeaderDelegate {
const _TabBarDelegate(this.tabBar);
final TabBar tabBar;
double get minExtent => tabBar.preferredSize.height;
double get maxExtent => tabBar.preferredSize.height;
TabController? get controller => tabBar.controller;
/// PageViewのスクロール量を[0~1]で取得する
double get animationValue => controller?.animation?.value ?? 0;
/// [0~1]で生成されるデータを[-1~1]に変換する
double get indicatorPosition => animationValue * 2 - 1;
/// 現在表示されているWidget
Widget get currentWidget => tabBar.tabs[controller?.index ?? 0];
Widget build(context, shrinkOffset, overlapsContent) {
return Container(
color: Colors.white,
child: Stack(
children: [
AnimatedAlign(
alignment: Alignment(indicatorPosition, 0),
duration: const Duration(milliseconds: 1),
child: Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 8),
width: MediaQuery.of(context).size.width / 2,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.red,
),
child: Opacity(opacity: 0, child: currentWidget),
),
),
),
Container(color: Colors.transparent, child: tabBar),
],
),
);
}
bool shouldRebuild(_TabBarDelegate oldDelegate) {
return tabBar != oldDelegate.tabBar;
}
}
Discussion