如何切换到另一个选项卡屏幕?
How do I switch to the another Tab Screen?
我想切换到另一个屏幕,当我点击标签栏上的另一个图标但它不起作用时。我总是在 HomeScreen() 中,无法切换到 HomeScreenMapView()。我想我在 ListView.builder
的 return 有问题,但我不知道如何继续。
我的代码:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import '../screens/home_screen.dart';
import '../screens/home_screen_map_view.dart';
class TabBarTop extends StatefulWidget {
@override
_TabBarTopState createState() => _TabBarTopState();
}
class _TabBarTopState extends State<TabBarTop> with SingleTickerProviderStateMixin {
bool _isAppbar = true;
ScrollController _scrollController = new ScrollController();
@override
void initState() {
super.initState();
_scrollController.addListener(() {
if (_scrollController.position.userScrollDirection ==
ScrollDirection.reverse) {
appBarStatus(false);
}
if (_scrollController.position.userScrollDirection ==
ScrollDirection.forward) {
appBarStatus(true);
}
});
}
void appBarStatus(bool status) {
setState(() {
_isAppbar = status;
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(MediaQuery.of(context).size.height * 0.12),
child: AnimatedContainer(
height: _isAppbar ? MediaQuery.of(context).size.height * 1 : 0.0,
duration: Duration(milliseconds: 200),
child: CustomAppBar(),
),
),
body: ListView.builder(
controller: _scrollController,
itemCount: 100,
itemBuilder: (BuildContext context, int index) {
return HomeScreen();
},
),
),
);
}
}
class CustomAppBar extends StatefulWidget {
@override
AppBarView createState() => new AppBarView();
}
class AppBarView extends State<CustomAppBar> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverAppBar(
title: Center(
heightFactor: 0,
child: Padding(
padding: const EdgeInsets.only(top: 7),
child: Image.asset(
'assets/images/***.png',
fit: BoxFit.cover,
scale: MediaQuery.of(context).size.width * 0.007,
alignment: Alignment.bottomCenter,
),
),
),
expandedHeight: MediaQuery.of(context).size.height * 0.12,
primary: true,
floating: true,
pinned: true,
bottom: TabBar(
indicatorColor: Color.fromRGBO(253, 166, 41, 1.0),
tabs: <Widget>[
Tab(
icon: Icon(Icons.list),
),
Tab(
icon: Icon(Icons.location_on),
),
],
),
forceElevated: false,
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: <Color>[
Color.fromRGBO(107, 176, 62, 1.0),
Color.fromRGBO(153, 199, 58, 1.0),
],
),
),
),
)
];
},
body: TabBarView(
children: <Widget>[
HomeScreen(),
HomeScreenMapView(),
],
),
),
);
}
}
谢谢:)
我认为您不需要 TabBarTop class 来实现,您只能使用提供该功能的 CustomAppBar class。
我不知道我目前对您的问题和需求了解多少,但我正在回答。
希望以下代码对您有所帮助。
直接从您的 main 调用 TabBarTop。
class TabBarTop extends StatefulWidget {
@override
_TabBarTopState createState() => _TabBarTopState();
}
class _TabBarTopState extends State<TabBarTop>
with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 50.0,
floating: true,
snap: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Text("Collapsing Toolbar",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
)),
background: Image.network(
"https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&h=350",
fit: BoxFit.cover,
)),
),
SliverPersistentHeader(
delegate: _SliverAppBarDelegate(
TabBar(
labelColor: Colors.black87,
unselectedLabelColor: Colors.grey,
tabs: [
Tab(icon: Icon(Icons.info), text: "Tab 1"),
Tab(icon: Icon(Icons.lightbulb_outline), text: "Tab 2"),
],
),
),
pinned: true,
),
];
},
body: TabBarView(
children: <Widget>[
HomeScreen(),
Container(
child: Center(child: Text("cds2")),
),
],
),
),
),
),
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: ListView.builder(
itemExtent: 150,
itemCount: 10,
itemBuilder: (_, index) {
return Text("csca $index");
},
),
);
}
}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate(this._tabBar);
final TabBar _tabBar;
@override
double get minExtent => _tabBar.preferredSize.height;
@override
double get maxExtent => _tabBar.preferredSize.height;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return new Container(
color: Colors.white,
child: _tabBar,
);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return false;
}
}
我想切换到另一个屏幕,当我点击标签栏上的另一个图标但它不起作用时。我总是在 HomeScreen() 中,无法切换到 HomeScreenMapView()。我想我在 ListView.builder
的 return 有问题,但我不知道如何继续。
我的代码:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import '../screens/home_screen.dart';
import '../screens/home_screen_map_view.dart';
class TabBarTop extends StatefulWidget {
@override
_TabBarTopState createState() => _TabBarTopState();
}
class _TabBarTopState extends State<TabBarTop> with SingleTickerProviderStateMixin {
bool _isAppbar = true;
ScrollController _scrollController = new ScrollController();
@override
void initState() {
super.initState();
_scrollController.addListener(() {
if (_scrollController.position.userScrollDirection ==
ScrollDirection.reverse) {
appBarStatus(false);
}
if (_scrollController.position.userScrollDirection ==
ScrollDirection.forward) {
appBarStatus(true);
}
});
}
void appBarStatus(bool status) {
setState(() {
_isAppbar = status;
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(MediaQuery.of(context).size.height * 0.12),
child: AnimatedContainer(
height: _isAppbar ? MediaQuery.of(context).size.height * 1 : 0.0,
duration: Duration(milliseconds: 200),
child: CustomAppBar(),
),
),
body: ListView.builder(
controller: _scrollController,
itemCount: 100,
itemBuilder: (BuildContext context, int index) {
return HomeScreen();
},
),
),
);
}
}
class CustomAppBar extends StatefulWidget {
@override
AppBarView createState() => new AppBarView();
}
class AppBarView extends State<CustomAppBar> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverAppBar(
title: Center(
heightFactor: 0,
child: Padding(
padding: const EdgeInsets.only(top: 7),
child: Image.asset(
'assets/images/***.png',
fit: BoxFit.cover,
scale: MediaQuery.of(context).size.width * 0.007,
alignment: Alignment.bottomCenter,
),
),
),
expandedHeight: MediaQuery.of(context).size.height * 0.12,
primary: true,
floating: true,
pinned: true,
bottom: TabBar(
indicatorColor: Color.fromRGBO(253, 166, 41, 1.0),
tabs: <Widget>[
Tab(
icon: Icon(Icons.list),
),
Tab(
icon: Icon(Icons.location_on),
),
],
),
forceElevated: false,
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: <Color>[
Color.fromRGBO(107, 176, 62, 1.0),
Color.fromRGBO(153, 199, 58, 1.0),
],
),
),
),
)
];
},
body: TabBarView(
children: <Widget>[
HomeScreen(),
HomeScreenMapView(),
],
),
),
);
}
}
谢谢:)
我认为您不需要 TabBarTop class 来实现,您只能使用提供该功能的 CustomAppBar class。
我不知道我目前对您的问题和需求了解多少,但我正在回答。
希望以下代码对您有所帮助。
直接从您的 main 调用 TabBarTop。
class TabBarTop extends StatefulWidget {
@override
_TabBarTopState createState() => _TabBarTopState();
}
class _TabBarTopState extends State<TabBarTop>
with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 50.0,
floating: true,
snap: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Text("Collapsing Toolbar",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
)),
background: Image.network(
"https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&h=350",
fit: BoxFit.cover,
)),
),
SliverPersistentHeader(
delegate: _SliverAppBarDelegate(
TabBar(
labelColor: Colors.black87,
unselectedLabelColor: Colors.grey,
tabs: [
Tab(icon: Icon(Icons.info), text: "Tab 1"),
Tab(icon: Icon(Icons.lightbulb_outline), text: "Tab 2"),
],
),
),
pinned: true,
),
];
},
body: TabBarView(
children: <Widget>[
HomeScreen(),
Container(
child: Center(child: Text("cds2")),
),
],
),
),
),
),
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: ListView.builder(
itemExtent: 150,
itemCount: 10,
itemBuilder: (_, index) {
return Text("csca $index");
},
),
);
}
}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate(this._tabBar);
final TabBar _tabBar;
@override
double get minExtent => _tabBar.preferredSize.height;
@override
double get maxExtent => _tabBar.preferredSize.height;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return new Container(
color: Colors.white,
child: _tabBar,
);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return false;
}
}