Open name27 opened 1 year ago
TabBar
import 'package:flutter/material.dart'; import 'package:sfac_design_flutter/sfac_design_flutter.dart'; import 'page_controller.dart'; class SFTabBar extends StatefulWidget { const SFTabBar( {super.key, required this.tabs, this.focusedColor, this.width, required this.height, this.backgroundColor, this.borderColor, this.borderBottom, this.borderWidth = 4.0, this.physics, this.textStyle, required this.pageController, this.duration, this.curve}); // 탭 바 메뉴 final List<Widget> tabs; //포커스될 때 색 final Color? focusedColor; //가로 넓이 final double? width; //높이 final double height; // 탭 배경색 final Color? backgroundColor; //탭 테두리색 final Color? borderColor; // 바텀보더 final BorderSide? borderBottom; //보더 테두리 두께 final double borderWidth; // 스크롤 피지컬 final ScrollPhysics? physics; // 메뉴 텍스트 스타일 final TextStyle? textStyle; // 페이지 컨트롤러 final SFPageController pageController; // 페이지 이동 시간 final Duration? duration; // 페이지 이동 효과 final Curve? curve; @override State<SFTabBar> createState() => _TabState(); } class _TabState extends State<SFTabBar> { int _index = 0; List<bool> isHover = []; @override void initState() { super.initState(); isHover = List.generate(widget.tabs.length, (index) => false); _index = widget.pageController.initialPage; widget.pageController.addListener(_tabListener); } @override Widget build(BuildContext context) { return Column( children: [ SizedBox( width: widget.width, height: widget.height, child: ListView.builder( physics: widget.physics ?? const NeverScrollableScrollPhysics(), scrollDirection: Axis.horizontal, itemCount: widget.tabs.length, itemBuilder: (context, index) { Widget? tabsText; TextStyle? tabsStyle; tabsStyle = widget.textStyle ?? SFTextStyle.b3M16( color: _index == index ? widget.focusedColor ?? SFColor.primary100 : Colors.black, ); tabsText = AnimatedDefaultTextStyle( style: tabsStyle, duration: kThemeChangeDuration, child: widget.tabs[index], ); return InkWell( splashColor: Colors.transparent, highlightColor: Colors.transparent, onTap: () { widget.pageController.animateToPage( index, duration: widget.duration ?? const Duration(milliseconds: 300), curve: widget.curve ?? Curves.ease, ); }, hoverColor: Colors.transparent, onHover: (value) { setState(() { isHover[index] = value; }); }, child: Container( width: widget.width != null ? widget.width! / widget.tabs.length : MediaQuery.of(context).size.width / widget.tabs.length, decoration: BoxDecoration( color: widget.backgroundColor, border: Border( bottom: isHover[index] ? widget.borderBottom ?? BorderSide( color: widget.borderColor ?? SFColor.primary100, width: widget.borderWidth, ) : _index == index ? widget.borderBottom ?? BorderSide( color: widget.borderColor ?? SFColor.primary100, width: widget.borderWidth, ) : BorderSide.none, ), ), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ isHover[index] ? SizedBox( height: widget.borderBottom != null || widget.borderBottom != BorderSide.none ? widget.borderWidth : null, ) : _index != index ? const SizedBox() : SizedBox( height: widget.borderBottom != null || widget.borderBottom != BorderSide.none ? widget.borderWidth : null, ), tabsText, ], ), ), ), ); }, ), ), ], ); } void _tabListener() { if (_index != widget.pageController.page!.round()) { setState(() { _index = widget.pageController.page!.round(); }); } } @override void dispose() { widget.pageController.removeListener(_tabListener); super.dispose(); } }
TabBarVIew
import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'page_controller.dart'; class SFTabBarView extends StatelessWidget { const SFTabBarView({ super.key, required this.tabController, required this.views, this.physics, this.dragStartBehavior, this.onPageChanged, // required this.height, }); // 페이지 컨트롤러 final SFPageController tabController; // PageView body 리스트 final List<Widget> views; // PageView ScrollPhysics final ScrollPhysics? physics; // PageView DragStartBehavior final DragStartBehavior? dragStartBehavior; // PageView onPageChanged final Function(int)? onPageChanged; //final double height; @override Widget build(BuildContext context) { return Expanded( child: PageView( onPageChanged: onPageChanged, dragStartBehavior: dragStartBehavior ?? DragStartBehavior.start, controller: tabController, physics: physics ?? const ClampingScrollPhysics(), children: views, ), ); } }
import 'package:flutter/material.dart'; class SFPageController extends PageController { SFPageController({ required this.length, int initialPage = 0, bool keepPage = true, double viewportFraction = 1.0, }) : super( initialPage: initialPage, keepPage: keepPage, viewportFraction: viewportFraction, ); final int length; }
TabBar
TabBarVIew
pageController