flutter click tab 隐藏在容器下
flutter click tab hide under container
我是flutter初学者
我正在开发一个 flutter 应用程序。
这是我的 flutter 应用程序屏幕。
当我点击书签标签栏时,我想将标记的部分隐藏为蓝色。
我尝试了几种方法,但我无法实现我的目标。
我真的需要你的帮助。
我附上了我的全部代码。
import 'package:botanic_flutter/login_page.dart';
import 'package:botanic_flutter/main.dart';
import 'package:botanic_flutter/root_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:botanic_flutter/custom_color_scheme.dart';
import 'package:google_sign_in/google_sign_in.dart';
class AccountPage extends StatefulWidget {
final String userUid;
AccountPage(this.userUid);
@override
_AccountPageState createState() => _AccountPageState();
}
class _AccountPageState extends State<AccountPage>
with SingleTickerProviderStateMixin {
final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _Auth = FirebaseAuth.instance;
FirebaseUser _currentUser;
TabController _controller;
ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_controller = TabController(length: 2, vsync: this);
}
@override
void dispose() {
_controller.dispose();
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
bottom: true,
child: DefaultTabController(
length: 2,
child: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (context, isScrolled) {
return <Widget>[
SliverList(
delegate: SliverChildListDelegate([
_detailedBody()
]),
),
SliverPersistentHeader(
pinned: true,
delegate: TabBarDelegate(
Column(
children: <Widget>[
TabBar(
unselectedLabelColor: Theme.of(context).colorScheme.greyColor,
labelColor: Theme.of(context).colorScheme.mainColor,
controller: _controller,
indicatorColor: Theme.of(context).colorScheme.mainColor,
tabs: [
Container(
height: 80,
padding: EdgeInsets.only(top: 10),
child: Tab(
icon: const Icon(Icons.home,
),
text: 'PLANTS',
),
),
Container(
height: 80,
padding: EdgeInsets.only(top: 10),
child: Tab(
icon: const Icon(Icons.bookmark_border,
),
text: 'BOOKMARK',
),
)
],
),
_bottomButtons(tabindi)
],
),
),
),
];
},
body: SizedBox(
height: MediaQuery.of(context).size.height,
child: TabBarView(
controller: _controller,
children: <Widget>[
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0),
itemCount: notes.length,
itemBuilder: (context, index) => Card(
child: Image.network(notes[index],
fit: BoxFit.cover,
),
),
),
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0),
itemCount: notes.length,
itemBuilder: (context, index) => Card(
child: Image.network(notes[index],
fit: BoxFit.cover,
),
),
)
],
),
),
),
),
),
);
}
Widget _detailedBody() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width * 3 / 4,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'http://www.korea.kr/newsWeb/resources/attaches/2017.08/03/3737_cp.jpg'),
),
),
),
Container(
transform: Matrix4.translationValues(0.0, -41.0, 0.0),
child: Column(
children: <Widget>[
Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
width: 90.0,
height: 90.0,
child: CircleAvatar(
backgroundColor: Colors.white,
),
),
SizedBox(
width: 82.0,
height: 82.0,
child: CircleAvatar(
backgroundImage: NetworkImage(
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG')),
),
Container(
width: 90.0,
height: 90.0,
alignment: Alignment.bottomRight,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
width: 28.0,
height: 28.0,
child: FloatingActionButton(
onPressed: null,
backgroundColor: Colors.white,
//child: Icon(Icons.add),
),
),
SizedBox(
width: 25.0,
height: 25.0,
child: FloatingActionButton(
onPressed: null,
backgroundColor:
Theme.of(context).colorScheme.mainColor,
child: Icon(Icons.add),
),
),
],
))
],
),
Padding(padding: EdgeInsets.all(5.0)),
Text(
'nickname',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24.0),
),
Padding(padding: EdgeInsets.all(5.0)),
Text(
'introduce',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
),
Padding(padding: EdgeInsets.all(9.0)),
FlatButton(
onPressed: () {
signOutWithGoogle().then((_) {
Navigator.popUntil(context, ModalRoute.withName('/'));
});
},
color: Theme.of(context).colorScheme.mainColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0)),
child: Text('로그아웃'),
),
Padding(padding: EdgeInsets.all(9.0)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Column(
children: <Widget>[
Text(
'0',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16.0),
),
Text(
'식물수',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
],
),
Column(
children: <Widget>[
Text(
'0',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16.0),
),
Text(
'팔로워',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
],
),
Column(
children: <Widget>[
Text(
'0',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16.0),
),
Text(
'팔로잉',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
],
)
],
)
],
),
),
],
);
}
var tabindi = 0;
Widget _bottomButtons(tabindi) {
print(tabindi);
return tabindi == 0
? Container(
child: Row(
children: <Widget>[
Padding(
padding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
child: Icon(
Icons.clear_all,
color: Colors.grey,
),
),
Container(
width: MediaQuery.of(context).size.width/3*1.4,
child: DropdownButton<String>(
isExpanded: true,
items: <String>['Foo', 'Bar'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (_) {},
),
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
child: Icon(
Icons.mode_edit,
color: Colors.grey,
),
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 1.0),
child: Icon(
Icons.delete,
color: Colors.grey,
),
),
Padding(
padding: EdgeInsets.all(4.0),
),
Container(
height: 30,
width: MediaQuery.of(context).size.width/4.5,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.mainColor,
borderRadius: BorderRadius.all(Radius.circular(20)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.shade200,
offset: Offset(2, 4),
blurRadius: 5,
spreadRadius: 2)
],
),
child: FlatButton(
child: Text(
"+식물등록",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.white,
),
),
onPressed: () => {
},
),
),
],
),
)
:
Container();
}
List<String> notes = [
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG',
'https://lh3.googleusercontent.com/proxy/BKvyuWq6b5apNOqvSw3VxB-QhezYHAoX1AptJdWPl-Ktq-Efm2gotbeXFtFlkr_ZPZmpEHc2BsKTC9oFQgzBimKsf5oRtTqOGdlO3MTfwiOT54E5m-lCtt6ANOMzmhNsYMGRp9Pg1NzjwMRUWNoWX0oJEFcnFvjOj2Rr4LtZpkXyiQFO',
'https://img1.daumcdn.net/thumb/R720x0.q80/?scode=mtistory2&fname=http%3A%2F%2Fcfile28.uf.tistory.com%2Fimage%2F2343174F58DBC14C2ECB8B',
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG',
'https://lh3.googleusercontent.com/proxy/BKvyuWq6b5apNOqvSw3VxB-QhezYHAoX1AptJdWPl-Ktq-Efm2gotbeXFtFlkr_ZPZmpEHc2BsKTC9oFQgzBimKsf5oRtTqOGdlO3MTfwiOT54E5m-lCtt6ANOMzmhNsYMGRp9Pg1NzjwMRUWNoWX0oJEFcnFvjOj2Rr4LtZpkXyiQFO',
'https://img1.daumcdn.net/thumb/R720x0.q80/?scode=mtistory2&fname=http%3A%2F%2Fcfile28.uf.tistory.com%2Fimage%2F2343174F58DBC14C2ECB8B',
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG',
'https://lh3.googleusercontent.com/proxy/BKvyuWq6b5apNOqvSw3VxB-QhezYHAoX1AptJdWPl-Ktq-Efm2gotbeXFtFlkr_ZPZmpEHc2BsKTC9oFQgzBimKsf5oRtTqOGdlO3MTfwiOT54E5m-lCtt6ANOMzmhNsYMGRp9Pg1NzjwMRUWNoWX0oJEFcnFvjOj2Rr4LtZpkXyiQFO',
'https://img1.daumcdn.net/thumb/R720x0.q80/?scode=mtistory2&fname=http%3A%2F%2Fcfile28.uf.tistory.com%2Fimage%2F2343174F58DBC14C2ECB8B',
];
Future<void> signOutWithGoogle() async {
// Sign out with firebase
await _Auth.signOut();
// Sign out with google
await _googleSignIn.signOut();
}
}
class TabBarDelegate extends SliverPersistentHeaderDelegate {
TabBarDelegate(this._tabBar);
final Column _tabBar;
@override
double get minExtent => 130.0;
@override
double get maxExtent => 130.0;
@override
Widget build(BuildContext context, double shrinkOffset,
bool overlapsContent) {
return Container(
color: Color(0xFFFAFAFA),
height: 130.0,
child: _tabBar
);
}
@override
bool shouldRebuild(covariant TabBarDelegate oldDelegate) {
return false;
}
}
期待您的回答。
谢谢!
使用Offstage
小部件
Offstage(
offstage: _controller.index == 1,
child: _bottomButtons(tabindi)
),
点击时更新 TabBar
TabBar(onTap: (_) => setState((){}));
我是flutter初学者
我正在开发一个 flutter 应用程序。
这是我的 flutter 应用程序屏幕。 当我点击书签标签栏时,我想将标记的部分隐藏为蓝色。 我尝试了几种方法,但我无法实现我的目标。 我真的需要你的帮助。
我附上了我的全部代码。
import 'package:botanic_flutter/login_page.dart';
import 'package:botanic_flutter/main.dart';
import 'package:botanic_flutter/root_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:botanic_flutter/custom_color_scheme.dart';
import 'package:google_sign_in/google_sign_in.dart';
class AccountPage extends StatefulWidget {
final String userUid;
AccountPage(this.userUid);
@override
_AccountPageState createState() => _AccountPageState();
}
class _AccountPageState extends State<AccountPage>
with SingleTickerProviderStateMixin {
final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _Auth = FirebaseAuth.instance;
FirebaseUser _currentUser;
TabController _controller;
ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_controller = TabController(length: 2, vsync: this);
}
@override
void dispose() {
_controller.dispose();
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
bottom: true,
child: DefaultTabController(
length: 2,
child: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (context, isScrolled) {
return <Widget>[
SliverList(
delegate: SliverChildListDelegate([
_detailedBody()
]),
),
SliverPersistentHeader(
pinned: true,
delegate: TabBarDelegate(
Column(
children: <Widget>[
TabBar(
unselectedLabelColor: Theme.of(context).colorScheme.greyColor,
labelColor: Theme.of(context).colorScheme.mainColor,
controller: _controller,
indicatorColor: Theme.of(context).colorScheme.mainColor,
tabs: [
Container(
height: 80,
padding: EdgeInsets.only(top: 10),
child: Tab(
icon: const Icon(Icons.home,
),
text: 'PLANTS',
),
),
Container(
height: 80,
padding: EdgeInsets.only(top: 10),
child: Tab(
icon: const Icon(Icons.bookmark_border,
),
text: 'BOOKMARK',
),
)
],
),
_bottomButtons(tabindi)
],
),
),
),
];
},
body: SizedBox(
height: MediaQuery.of(context).size.height,
child: TabBarView(
controller: _controller,
children: <Widget>[
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0),
itemCount: notes.length,
itemBuilder: (context, index) => Card(
child: Image.network(notes[index],
fit: BoxFit.cover,
),
),
),
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0),
itemCount: notes.length,
itemBuilder: (context, index) => Card(
child: Image.network(notes[index],
fit: BoxFit.cover,
),
),
)
],
),
),
),
),
),
);
}
Widget _detailedBody() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width * 3 / 4,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'http://www.korea.kr/newsWeb/resources/attaches/2017.08/03/3737_cp.jpg'),
),
),
),
Container(
transform: Matrix4.translationValues(0.0, -41.0, 0.0),
child: Column(
children: <Widget>[
Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
width: 90.0,
height: 90.0,
child: CircleAvatar(
backgroundColor: Colors.white,
),
),
SizedBox(
width: 82.0,
height: 82.0,
child: CircleAvatar(
backgroundImage: NetworkImage(
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG')),
),
Container(
width: 90.0,
height: 90.0,
alignment: Alignment.bottomRight,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
width: 28.0,
height: 28.0,
child: FloatingActionButton(
onPressed: null,
backgroundColor: Colors.white,
//child: Icon(Icons.add),
),
),
SizedBox(
width: 25.0,
height: 25.0,
child: FloatingActionButton(
onPressed: null,
backgroundColor:
Theme.of(context).colorScheme.mainColor,
child: Icon(Icons.add),
),
),
],
))
],
),
Padding(padding: EdgeInsets.all(5.0)),
Text(
'nickname',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24.0),
),
Padding(padding: EdgeInsets.all(5.0)),
Text(
'introduce',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
),
Padding(padding: EdgeInsets.all(9.0)),
FlatButton(
onPressed: () {
signOutWithGoogle().then((_) {
Navigator.popUntil(context, ModalRoute.withName('/'));
});
},
color: Theme.of(context).colorScheme.mainColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0)),
child: Text('로그아웃'),
),
Padding(padding: EdgeInsets.all(9.0)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Column(
children: <Widget>[
Text(
'0',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16.0),
),
Text(
'식물수',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
],
),
Column(
children: <Widget>[
Text(
'0',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16.0),
),
Text(
'팔로워',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
],
),
Column(
children: <Widget>[
Text(
'0',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16.0),
),
Text(
'팔로잉',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
],
)
],
)
],
),
),
],
);
}
var tabindi = 0;
Widget _bottomButtons(tabindi) {
print(tabindi);
return tabindi == 0
? Container(
child: Row(
children: <Widget>[
Padding(
padding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
child: Icon(
Icons.clear_all,
color: Colors.grey,
),
),
Container(
width: MediaQuery.of(context).size.width/3*1.4,
child: DropdownButton<String>(
isExpanded: true,
items: <String>['Foo', 'Bar'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (_) {},
),
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
child: Icon(
Icons.mode_edit,
color: Colors.grey,
),
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 1.0),
child: Icon(
Icons.delete,
color: Colors.grey,
),
),
Padding(
padding: EdgeInsets.all(4.0),
),
Container(
height: 30,
width: MediaQuery.of(context).size.width/4.5,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.mainColor,
borderRadius: BorderRadius.all(Radius.circular(20)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.shade200,
offset: Offset(2, 4),
blurRadius: 5,
spreadRadius: 2)
],
),
child: FlatButton(
child: Text(
"+식물등록",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.white,
),
),
onPressed: () => {
},
),
),
],
),
)
:
Container();
}
List<String> notes = [
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG',
'https://lh3.googleusercontent.com/proxy/BKvyuWq6b5apNOqvSw3VxB-QhezYHAoX1AptJdWPl-Ktq-Efm2gotbeXFtFlkr_ZPZmpEHc2BsKTC9oFQgzBimKsf5oRtTqOGdlO3MTfwiOT54E5m-lCtt6ANOMzmhNsYMGRp9Pg1NzjwMRUWNoWX0oJEFcnFvjOj2Rr4LtZpkXyiQFO',
'https://img1.daumcdn.net/thumb/R720x0.q80/?scode=mtistory2&fname=http%3A%2F%2Fcfile28.uf.tistory.com%2Fimage%2F2343174F58DBC14C2ECB8B',
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG',
'https://lh3.googleusercontent.com/proxy/BKvyuWq6b5apNOqvSw3VxB-QhezYHAoX1AptJdWPl-Ktq-Efm2gotbeXFtFlkr_ZPZmpEHc2BsKTC9oFQgzBimKsf5oRtTqOGdlO3MTfwiOT54E5m-lCtt6ANOMzmhNsYMGRp9Pg1NzjwMRUWNoWX0oJEFcnFvjOj2Rr4LtZpkXyiQFO',
'https://img1.daumcdn.net/thumb/R720x0.q80/?scode=mtistory2&fname=http%3A%2F%2Fcfile28.uf.tistory.com%2Fimage%2F2343174F58DBC14C2ECB8B',
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG',
'https://lh3.googleusercontent.com/proxy/BKvyuWq6b5apNOqvSw3VxB-QhezYHAoX1AptJdWPl-Ktq-Efm2gotbeXFtFlkr_ZPZmpEHc2BsKTC9oFQgzBimKsf5oRtTqOGdlO3MTfwiOT54E5m-lCtt6ANOMzmhNsYMGRp9Pg1NzjwMRUWNoWX0oJEFcnFvjOj2Rr4LtZpkXyiQFO',
'https://img1.daumcdn.net/thumb/R720x0.q80/?scode=mtistory2&fname=http%3A%2F%2Fcfile28.uf.tistory.com%2Fimage%2F2343174F58DBC14C2ECB8B',
];
Future<void> signOutWithGoogle() async {
// Sign out with firebase
await _Auth.signOut();
// Sign out with google
await _googleSignIn.signOut();
}
}
class TabBarDelegate extends SliverPersistentHeaderDelegate {
TabBarDelegate(this._tabBar);
final Column _tabBar;
@override
double get minExtent => 130.0;
@override
double get maxExtent => 130.0;
@override
Widget build(BuildContext context, double shrinkOffset,
bool overlapsContent) {
return Container(
color: Color(0xFFFAFAFA),
height: 130.0,
child: _tabBar
);
}
@override
bool shouldRebuild(covariant TabBarDelegate oldDelegate) {
return false;
}
}
期待您的回答。
谢谢!
使用Offstage
小部件
Offstage(
offstage: _controller.index == 1,
child: _bottomButtons(tabindi)
),
点击时更新 TabBar
TabBar(onTap: (_) => setState((){}));