这是我想要的输出。我仍然是新的flutter,所以谁可以让我知道,如果已经有一个小部件,这种开关或我应该如何做一个??此外,我希望数据显示在这个按钮下面的变化,如果我选择其他按钮,但我猜这是显而易见的。先谢了。
e5nszbig1#
您可以使用TabBar小部件来实现这一点,我添加了一个完整的示例来演示如何使用TabBar小部件来创建它:
TabBar
class StackOver extends StatefulWidget { @override _StackOverState createState() => _StackOverState(); } class _StackOverState extends State<StackOver> with SingleTickerProviderStateMixin { TabController _tabController; @override void initState() { _tabController = TabController(length: 2, vsync: this); super.initState(); } @override void dispose() { super.dispose(); _tabController.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( 'Tab bar', ), ), body: Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ // give the tab bar a height [can change hheight to preferred height] Container( height: 45, decoration: BoxDecoration( color: Colors.grey[300], borderRadius: BorderRadius.circular( 25.0, ), ), child: TabBar( controller: _tabController, // give the indicator a decoration (color and border radius) indicator: BoxDecoration( borderRadius: BorderRadius.circular( 25.0, ), color: Colors.green, ), labelColor: Colors.white, unselectedLabelColor: Colors.black, tabs: [ // first tab [you can add an icon using the icon property] Tab( text: 'Place Bid', ), // second tab [you can add an icon using the icon property] Tab( text: 'Buy Now', ), ], ), ), // tab bar view here Expanded( child: TabBarView( controller: _tabController, children: [ // first tab bar view widget Center( child: Text( 'Place Bid', style: TextStyle( fontSize: 25, fontWeight: FontWeight.w600, ), ), ), // second tab bar view widget Center( child: Text( 'Buy Now', style: TextStyle( fontSize: 25, fontWeight: FontWeight.w600, ), ), ), ], ), ), ], ), ), ); } }
atmip9wb2#
试试这个,你必须change一些colour和font:-
change
colour
font
import 'package:flutter/material.dart'; typedef SwitchOnChange = Function(int); class CustomSwitch extends StatefulWidget { SwitchOnChange onChange; CustomSwitch({this.onChange}); @override State<StatefulWidget> createState() { return CustomSwitchState(); } } class CustomSwitchState extends State<CustomSwitch> with TickerProviderStateMixin { AnimationController controller; Animation animation; GlobalKey key = GlobalKey(); @override void initState() { Future.delayed(Duration(milliseconds: 100)).then((v) { controller = AnimationController( vsync: this, duration: Duration(milliseconds: 300)); tabWidth = key.currentContext.size.width / 2; // var width = (media.size.width - (2 * media.padding.left)) / 2; animation = Tween<double>(begin: 0, end: tabWidth).animate(controller); setState(() {}); controller.addListener(() { setState(() {}); }); }); super.initState(); } var selectedValue = 0; double tabWidth = 0; @override Widget build(BuildContext context) { return GestureDetector( onTap: () { selectedValue == 0 ? this.controller.forward() : controller.reverse(); selectedValue = selectedValue == 0 ? 1 : 0; }, child: Container( key: key, height: 44, decoration: BoxDecoration( color: Colors.grey, borderRadius: BorderRadius.circular(22)), child: Stack( children: <Widget>[ Row( children: <Widget>[ Transform.translate( offset: Offset(animation?.value ?? 0, 0), child: Container( height: 44, width: tabWidth, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(22), boxShadow: [ BoxShadow(color: Colors.grey, blurRadius: 3), ]), ), ), ], ), Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Container( width: tabWidth, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Icon(Icons.directions_walk), SizedBox(width: 5), Text("Place Bid") ], ), ), Container( width: tabWidth, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Icon(Icons.directions_walk), SizedBox(width: 5), Text("Buy now") ], ), ) ], ), ), ], ), ), ); } }
wsewodh23#
您也可以使用PageView小工具。
const double borderRadius = 25.0; class CustomSwitchState extends StatefulWidget { @override _CustomSwitchStateState createState() => _CustomSwitchStateState(); } class _CustomSwitchStateState extends State<CustomSwitchState> with SingleTickerProviderStateMixin { PageController _pageController; int activePageIndex = 0; @override void dispose() { _pageController.dispose(); super.dispose(); } @override void initState() { super.initState(); _pageController = PageController(); } @override Widget build(BuildContext context) { return Scaffold( body: SingleChildScrollView( physics: const ClampingScrollPhysics(), child: GestureDetector( onTap: () { FocusScope.of(context).requestFocus(FocusNode()); }, child: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, child: Column( mainAxisSize: MainAxisSize.max, children: <Widget>[ Padding( padding: const EdgeInsets.only(top: 20.0), child: _menuBar(context), ), Expanded( flex: 2, child: PageView( controller: _pageController, physics: const ClampingScrollPhysics(), onPageChanged: (int i) { FocusScope.of(context).requestFocus(FocusNode()); setState(() { activePageIndex = i; }); }, children: <Widget>[ ConstrainedBox( constraints: const BoxConstraints.expand(), child: Center(child: Text("Place Bid"),), ), ConstrainedBox( constraints: const BoxConstraints.expand(), child: Center(child: Text("Buy Now"),), ), ], ), ), ], ), ), ), )); } Widget _menuBar(BuildContext context) { return Container( width: 300.0, height: 50.0, decoration: const BoxDecoration( color: Color(0XFFE0E0E0), borderRadius: BorderRadius.all(Radius.circular(borderRadius)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Expanded( child: InkWell( borderRadius: BorderRadius.all(Radius.circular(borderRadius)), onTap: _onPlaceBidButtonPress, child: Container( width: MediaQuery.of(context).size.width, padding: EdgeInsets.symmetric(vertical: 15), alignment: Alignment.center, decoration: (activePageIndex == 0) ? const BoxDecoration( color: Colors.green, borderRadius: BorderRadius.all(Radius.circular(borderRadius)), ) : null, child: Text( "Place Bid", style: (activePageIndex == 0) ? TextStyle(color: Colors.white) : TextStyle(color: Colors.black), ), ), ), ), Expanded( child: InkWell( borderRadius: BorderRadius.all(Radius.circular(borderRadius)), onTap: _onBuyNowButtonPress, child: Container( width: MediaQuery.of(context).size.width, padding: EdgeInsets.symmetric(vertical: 15), alignment: Alignment.center, decoration: (activePageIndex == 1) ? const BoxDecoration( color: Colors.green, borderRadius: BorderRadius.all(Radius.circular(borderRadius)), ) : null, child: Text( "Buy Now", style: (activePageIndex == 1) ? TextStyle(color: Colors.white, fontWeight: FontWeight.bold) : TextStyle(color: Colors.black, fontWeight: FontWeight.bold), ), ), ), ), ], ), ); } void _onPlaceBidButtonPress() { _pageController.animateToPage(0, duration: const Duration(milliseconds: 500), curve: Curves.decelerate); } void _onBuyNowButtonPress() { _pageController.animateToPage(1, duration: const Duration(milliseconds: 500), curve: Curves.decelerate); } }
输出
pod7payv4#
输出:
import 'package:flutter/material.dart'; import 'package:icons_helper/icons_helper.dart'; class DetailScreen extends StatefulWidget { var body; String title = ""; DetailScreen(this.body, this.title); @override _MainPageState createState() => _MainPageState(); } class _MainPageState extends State<DetailScreen> with TickerProviderStateMixin { late int _startingTabCount; List<Tab> _tabs = <Tab>[]; List<Widget> _generalWidgets = <Widget>[]; late TabController _tabController; @override void initState() { _startingTabCount = widget.body["related_modules"].length; _tabs = getTabs(_startingTabCount); _tabController = getTabController(); super.initState(); } @override void dispose() { _tabController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), bottom: TabBar( isScrollable: true, tabs: _tabs, controller: _tabController, ), flexibleSpace: Container( decoration: BoxDecoration( gradient: LinearGradient( colors: [ Colors.grey, Colors.blue, ], stops: [0.3, 1.0], ), ), ), leading: IconButton( icon: Icon(Icons.arrow_back_ios), color: Colors.white, onPressed: () { Navigator.of(context, rootNavigator: true).pop(context); }, ), actions: <Widget>[ IconButton( icon: Icon(Icons.skip_previous), color: Colors.white, onPressed: () { goToPreviousPage(); }, ), Container( margin: EdgeInsets.only(right: 15), child: IconButton( icon: Icon(Icons.skip_next), color: Colors.white, onPressed: () { goToNextPage(); }, ), ) ], ), body: Column( children: <Widget>[ Expanded( child: TabBarView( physics: NeverScrollableScrollPhysics(), controller: _tabController, children: getWidgets(), ), ), ], ), ); } TabController getTabController() { return TabController(length: _tabs.length, vsync: this) ..addListener(_updatePage); } Tab getTab(int widgetNumber) { return Tab( icon: Column( children: [ if (widget.body["related_modules"][widgetNumber]["icon"].toString() == "fa-comments-o") ...[ Icon( Icons.comment_outlined, ), ] else if (widget.body["related_modules"][widgetNumber]["icon"] .toString() == "fa-map-marker") ...[ Icon( Icons.location_on_rounded, ), ] else if (widget.body["related_modules"][widgetNumber]["icon"] .toString() == "fa-address-card") ...[ Icon( Icons.contact_page_sharp, ), ] else ...[ Icon( getIconUsingPrefix( name: widget.body["related_modules"][widgetNumber]["icon"] .toString() .substring(3), ), ) ] ], ), text: widget.body["related_modules"][widgetNumber]["label"].toString(), ); } Widget getWidget(int widgetNumber) { return Center( child: Text("Widget nr: $widgetNumber"), ); } List<Tab> getTabs(int count) { _tabs.clear(); for (int i = 0; i < count; i++) { _tabs.add(getTab(i)); } return _tabs; } List<Widget> getWidgets() { _generalWidgets.clear(); for (int i = 0; i < _tabs.length; i++) { _generalWidgets.add(getWidget(i)); } return _generalWidgets; } void _updatePage() { setState(() {}); } //Tab helpers bool isFirstPage() { return _tabController.index == 0; } bool isLastPage() { return _tabController.index == _tabController.length - 1; } void goToPreviousPage() { _tabController.animateTo(_tabController.index - 1); } void goToNextPage() { isLastPage() ? showDialog( context: context, builder: (context) => AlertDialog( title: Text("End reached"), content: Text("This is the last page."))) : _tabController.animateTo(_tabController.index + 1); } }
9jyewag05#
以下是我的变通方法,我认为这是最好的方法。
import 'package:flutter/material.dart'; class SettingsScreen extends StatelessWidget { const SettingsScreen({ super.key, }); @override Widget build(BuildContext context) { return DefaultTabController( length: 2, child: Scaffold( appBar: AppBar( title: const Text('Settings'), bottom: PreferredSize( preferredSize: Size.fromHeight(AppBar().preferredSize.height), child: Container( height: 50, padding: const EdgeInsets.symmetric( horizontal: 20, vertical: 5, ), child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular( 10, ), color: Colors.grey[200], ), child: TabBar( labelColor: Colors.white, unselectedLabelColor: Colors.black, indicator: BoxDecoration( borderRadius: BorderRadius.circular( 10, ), color: Colors.pink, ), tabs: const [ Tab( text: 'Basic', ), Tab( text: 'Advanced', ) ], ), ), ), ), ), body: const TabBarView( children: [ Center( child: Text( 'Basic Settings', style: TextStyle( fontSize: 30, ), ), ), Center( child: Text( 'Advanced Settings', style: TextStyle( fontSize: 30, ), ), ), ], ), ), ); } }
5条答案
按热度按时间e5nszbig1#
您可以使用
TabBar
小部件来实现这一点,我添加了一个完整的示例来演示如何使用TabBar
小部件来创建它:atmip9wb2#
试试这个,你必须
change
一些colour
和font
:-wsewodh23#
您也可以使用PageView小工具。
输出
pod7payv4#
输出:
9jyewag05#
以下是我的变通方法,我认为这是最好的方法。