Flutter SliverAppBar add widget to collapsed part - flutter

I'm currently developing a flutter mobile app by using sliver appbar and I want to add some widget to collapsed app bar.and also make background color to gradient. when I tried to add by using leading property it creates overflow and also the widget displays in the flexspacebar.
The above image is before scroll.
and this one is after scroll and I want to add some widget in the center of the blue part.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rehove/Widgets/sliver_card.dart';
import '../Widgets/action_button.dart';
class UserScreen extends StatelessWidget {
const UserScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
TextTheme _textTheme = Theme.of(context).textTheme;
return
AnnotatedRegion<SystemUiOverlayStyle>(
value: const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light
),
child: Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
collapsedHeight: 320,
pinned: true,
leadingWidth: 200,
leading: Padding(
padding: EdgeInsets.only(left:32),
child: GestureDetector(
onTap:()=>{
Navigator.pop(context)
},
child: Row(
children: [
Icon(Icons.arrow_back_ios),
Text('Back',style: _textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500,
fontSize: 16
),)
],
),
),
),
expandedHeight: 450,
flexibleSpace: FlexibleSpaceBar(
background: Stack(
children: [
Image.asset('assets/images/user.png',
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
),
Align(
alignment:Alignment.bottomCenter,
child: Container(
height: 102,
width: double.infinity,
color:Color(0xffD9D9D9).withOpacity(0.6),
child:Padding(
padding:const EdgeInsets.symmetric(horizontal: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Liya Dereje',style: _textTheme.bodyLarge?.copyWith(
color: Color(0xffffffff),
fontWeight: FontWeight.w500,
fontSize: 20
),),
Text('LiyaDereje2#gmail.com',style: _textTheme.bodyLarge?.copyWith(
color: Color(0xfff7f7f7),
fontWeight: FontWeight.w500,
fontSize: 12
),)
],
),
ActionButton(label: 'Edit Profile',
height: 38,
width: 20,
onPressed: () { },)
],
),
)
),
)
]
),
),
),
SliverToBoxAdapter(
child:Column(children: [
const SizedBox(height: 40,),
Row(
children: [
const Expanded(child: Divider(thickness: 1,)),
Text('Setting',style: _textTheme.bodySmall?.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400
),),
const Expanded(child: Divider(thickness: 1,)),
],
),
const SizedBox(height: 16,),
SliverCard(icon: Icons.notifications_outlined,title: 'Notification',amount: '4',),
const SizedBox(height: 10,),
SliverCard(icon: Icons.donut_small,title: 'Reports',amount: '4',),
const SizedBox(height: 10,),
SliverCard(icon: Icons.email_outlined,title: 'Email',amount: '5',),
const SizedBox(height: 10,),
SliverCard(icon: Icons.description_outlined,title: 'Terms of',amount: '3',),
const SizedBox(height: 10,),
SliverCard(icon: Icons.accessibility_new_rounded,title: 'Accessibility',amount: '4',),
const SizedBox(height: 10,),
SliverCard(icon: Icons.logout,title: 'Logout',amount: '4',),
const SizedBox(height: 10,),
SliverCard(icon: Icons.email_outlined,title: 'Email',amount: '5',),
const SizedBox(height: 10,),
SliverCard(icon: Icons.description_outlined,title: 'Terms of',amount: '3',),
const SizedBox(height: 10,),
SliverCard(icon: Icons.accessibility_new_rounded,title: 'Accessibility',amount: '4',),
const SizedBox(height: 10,),
],
)
)
],
),
)
);
}
}

Step 1:
First declare the varibale
bool lastStatus = true;
ScrollController? _nestedScrollController;
Step 2:
void _scrollListener() {
if (_isShrink != lastStatus) {
setState(() {
lastStatus = _isShrink;
});
}
}
bool get _isShrink {
return _nestedScrollController != null &&
_nestedScrollController!.hasClients &&
_nestedScrollController!.offset > (30.h - kToolbarHeight);
}
put above method inside the class
Step 3:
#override
void dispose() {
_nestedScrollController?.removeListener(_scrollListener);
_nestedScrollController?.dispose();
super.dispose();
}
#override
void initState() {
_nestedScrollController =
ScrollController(initialScrollOffset: 33.h - kToolbarHeight)
..addListener(_scrollListener);
}
Put the above method inside the init and dispose
Step 4:
Scaffold(
resizeToAvoidBottomInset: false,
body: NestedScrollView(
controller: _nestedScrollController,
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
TransitionsAppsBar(
isShrink: _isShrink,
….
…
),
];
},
body: child…
Step 5:
Use require code inside the below class
class TransitionsAppsBar extends StatelessWidget {
final bool isShrink;
final VoidCallback? onBackTap;
final VoidCallback? onInfoTap;
final VoidCallback? onTap;
final VoidCallback onAlertTap;
final GroupDetailsDTO? groupInfo;
final bool isOverDue;
const TransitionsAppsBar({
Key? key,
this.isShrink = true,
this.onBackTap,
this.onInfoTap,
this.groupInfo,
this.onTap,
this.isOverDue = false,
required this.onAlertTap,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return BlocBuilder<GroupBloc, GroupState>(
builder: (context, state) {
return SliverAppBar(
elevation: 2,
backgroundColor: AppTheme.secondaryColor,
pinned: true,
collapsedHeight: kToolbarHeight + (isOverDue ? 25 : 0),
centerTitle: true,
titleSpacing: 0,
leadingWidth: 21.w,
automaticallyImplyLeading: false,
bottom: !isOverDue
? null
: PreferredSize(
child: GestureDetector(
onTap: onAlertTap,
child: Container(
color: AppTheme.primaryColor_100,
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
Assets.icOverdue,
height: 20,
width: 20,
color: AppTheme.whiteColor,
),
const SizedBox(width: 4),
Text(
StringConstants.groupIsInactive,
style: Theme.of(context)
.textTheme
.caption!
.copyWith(color: AppTheme.whiteColor),
),
const SizedBox(width: 4),
Text(
StringConstants.learnMore,
style:
Theme.of(context).textTheme.caption!.copyWith(
color: AppTheme.whiteColor,
decoration: TextDecoration.underline,
),
),
],
),
),
),
preferredSize: const Size.fromHeight(0),
),
title: GestureDetector(
onTap: onTap,
child: Visibility(
visible: isShrink,
child: Container(
color: Colors.transparent,
width: 100.w,
height: kToolbarHeight,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Text(
groupInfo?.name ?? '',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style:
Theme.of(context).textTheme.caption!.copyWith(
fontSize: 14,
color: AppTheme.whiteColor,
overflow: TextOverflow.ellipsis,
),
),
),
if (groupInfo?.isOverdue ?? false) ...[
const SizedBox(width: 8),
GestureDetector(
onTap: onAlertTap,
child: Image.asset(
Assets.icOverdue,
height: 20,
width: 20,
),
),
]
],
),
if ((groupInfo?.id ?? 0) != 0)
Text(
"${(groupInfo?.memberDetails.length ?? 0).toString()} ${StringConstants.loopers}",
style: Theme.of(context)
.textTheme
.caption!
.copyWith(fontSize: 14, color: AppTheme.whiteColor),
)
else
Container(),
],
),
),
),
),
leading: Stack(
alignment: Alignment.centerLeft,
children: [
Container(
margin: EdgeInsets.only(left: 5.h),
child: Visibility(
visible: isShrink,
child: ((groupInfo?.id ?? 0) != 0)
? ProfilePic(
imageUrl: groupInfo?.image,
name: (groupInfo?.name.length ?? 0) <= 3 ||
groupInfo!.isIndividualGroup
? groupInfo?.name
: groupInfo?.name.characters.take(3).toString(),
picType: groupInfo!.isIndividualGroup
? StringConstants.systemGroup
: StringConstants.group,
)
: Container(),
),
),
BackButtonWidget(onBackTap: onBackTap),
],
),
expandedHeight: 30.h,
flexibleSpace: FlexibleSpaceBar(
background: Center(
child: Visibility(
visible: !isShrink,
child: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 12.h),
child: ((groupInfo?.id ?? 0) != 0)
? ProfilePic(
imageUrl: groupInfo?.image,
name: (groupInfo?.name.length ?? 0) <= 3 ||
groupInfo!.isIndividualGroup
? groupInfo?.name
: groupInfo?.name.characters.take(3).toString(),
picType: groupInfo!.isIndividualGroup
? StringConstants.systemGroup
: StringConstants.group,
sizeMultiplier: 2.5.h,
)
: Container(),
),
SizedBox(height: 2.h),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Flexible(
child: Padding(
padding: const EdgeInsets.only(left: 12),
child: Text(
groupInfo?.name ?? "",
maxLines: 2,
style:
Theme.of(context).textTheme.subtitle2!.copyWith(
color: AppTheme.whiteColor,
overflow: TextOverflow.ellipsis,
),
),
),
),
if (groupInfo?.isOverdue ?? false)
Padding(
padding: const EdgeInsets.only(right: 12, left: 8),
child: GestureDetector(
onTap: onAlertTap,
child: Image.asset(
Assets.icOverdue,
height: 20,
width: 20,
),
),
)
else
const SizedBox(width: 12),
],
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Text(
(groupInfo?.memberDetails ?? [])
.getMemberNames(groupInfo?.adminId ?? 0),
style: Theme.of(context)
.textTheme
.caption
?.copyWith(color: AppTheme.whiteColor),
),
),
],
),
),
)),
actions: [
Visibility(
visible: !groupInfo!.isIndividualGroup &&
!state.isFetchingGroupDetails,
child: GestureDetector(
onTap: onInfoTap,
child: Padding(
padding: const EdgeInsets.only(right: 10),
child: Image.asset(
Assets.icInfoGroup,
height: 25,
width: 25,
color: AppTheme.whiteColor,
),
),
),
)
],
);
},
);
}
}

Add another Stack that wraps your FlexibleSpaceBar and the widget you want in the middle when collapsed. Try this:
flexibleSpace: Stack(
children: [
Positioned.fill(
child: Align(
alignment: Alignment.center,
child: Text('I\'m in the center'),
),
),
FlexibleSpaceBar(
background: Stack(children: [
Image.asset(
'assets/images/user.png',
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 102,
width: double.infinity,
color: Color(0xffD9D9D9).withOpacity(0.6),
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 20),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'Liya Dereje',
style: _textTheme.bodyLarge?.copyWith(
color: Color(0xffffffff),
fontWeight: FontWeight.w500,
fontSize: 20),
),
Text(
'LiyaDereje2#gmail.com',
style: _textTheme.bodyLarge?.copyWith(
color: Color(0xfff7f7f7),
fontWeight: FontWeight.w500,
fontSize: 12),
)
],
),
ActionButton(
label: 'Edit Profile',
height: 38,
width: 20,
onPressed: () {},
)
],
),
)),
)
]),
),
],
),

Related

How can bind items details from the listview in flutter?

I need help on how to achive binding items from the list view into other widget. For example, I have a listview of Products to be sold, when a sale person click any product from the list, it should be added on top of the screen with it price, then more product can be added each time a sale person press new product from the listview. I have already tried different ways to achieve this. This is a sample of the screen I want to achieve.
This is what I have achieved so far
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class NewSale extends StatefulWidget {
const NewSale({Key? key}) : super(key: key);
#override
_NewSaleState createState() => _NewSaleState();
}
class _NewSaleState extends State<NewSale> {
TextEditingController searchingInput = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.green),
backgroundColor: Colors.white,
elevation: 0.0,
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(top: 8.0),
child: Text(
"Sales",
style: TextStyle(color: Color(0xff444444), fontSize: 19),
),
),
Text(
"Manage Sales",
style: TextStyle(color: Color(0xffa1a1a1), fontSize: 13),
),
],
),
actions: [
Builder(
builder: (context) => IconButton(
icon: Image.asset("assets/images/icons/sync_products.png"),
onPressed: () => {},
)),
],
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: const Icon(
Icons.arrow_back,
color: Colors.black,
size: 40, // Changing Drawer Icon Size
),
onPressed: () {
Navigator.pop(context);
},
);
},
),
),
bottomNavigationBar: new Container(
height: 70.0,
padding: EdgeInsets.only(top: 10),
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Flexible(
child: Container(
width: MediaQuery.of(context).size.width * 0.4,
child: Column(
children: [
MaterialButton(
elevation: 0.00,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xffFA7659),
width: 1,
style: BorderStyle.solid),
borderRadius: BorderRadius.circular(3)),
textColor: Colors.white,
color: Color(0xffFA7659),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(14.0),
child: Text('CLEAR',
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w300)),
),
],
),
],
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
),
Flexible(
child: Container(
width: MediaQuery.of(context).size.width * 0.4,
child: Column(
children: [
MaterialButton(
elevation: 0.00,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xff78BD42),
width: 1,
style: BorderStyle.solid),
borderRadius: BorderRadius.circular(3)),
textColor: Colors.white,
color: Color(0xff78BD42),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(14.0),
child: Text(
'CONFIRM',
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w300),
),
),
],
),
],
),
onPressed: () {},
),
],
),
),
),
],
),
),
body: SafeArea(
child: Container(
color: Colors.red,
height: MediaQuery.of(context).size.height * 1,
width: MediaQuery.of(context).size.width * 1,
child: Column(
children: [
Flexible(
child: Container(
height: MediaQuery.of(context).size.height * .5,
width: MediaQuery.of(context).size.width * 1,
color: Colors.grey,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'==== Product Cart ====',
style: TextStyle(color: Color(0xff5c5c5c)),
textAlign: TextAlign.center,
),
),
),
),
Flexible(
child: Container(
height: MediaQuery.of(context).size.height * .5,
width: MediaQuery.of(context).size.width * 1,
color: Colors.white,
child: Column(
children: [
Row(
children: [
Column(
children: [
Container(
padding: EdgeInsets.fromLTRB(15, 10, 0, 0),
child: MaterialButton(
elevation: 0.00,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xff828282),
width: 1,
style: BorderStyle.solid),
borderRadius: BorderRadius.circular(3)),
textColor: Colors.white,
color: Color(0xff828282),
child: Row(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Row(
children: [
Image.asset(
'assets/images/icons/scan.png',
width: 20,
height: 20,
),
Padding(
padding:
const EdgeInsets.all(14.0),
child: Text('SCAN',
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight:
FontWeight.w300)),
),
],
),
],
),
],
),
onPressed: () {},
),
),
],
),
Flexible(
child: Column(
children: [productSearchingField()],
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Flexible(
child: Container(
width: MediaQuery.of(context).size.width * 0.6,
padding: EdgeInsets.fromLTRB(15, 7, 15, 0),
child: Column(
children: [
MaterialButton(
elevation: 0.00,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xff78BD42),
width: 1,
style: BorderStyle.solid),
borderRadius: BorderRadius.circular(3)),
textColor: Colors.white,
color: Color(0xff78BD42),
child: Row(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Row(
children: [
Column(
children: [Icon(Icons.add)],
),
Column(
children: [
Padding(
padding:
const EdgeInsets.only(
top: 14.0,
bottom: 14.0),
child: Text(
'ADD NEW PRODUCT',
style: TextStyle(
fontSize: 14,
color: Colors.white,
fontWeight:
FontWeight
.w300),
),
),
],
),
],
),
],
),
],
),
onPressed: () {},
),
],
),
),
),
],
),
Flexible(
child: Container(
child: ListView.builder(
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: Image.asset(
'assets/images/icons/brand-identity.png',
width: 50,
height: 50,
),
trailing: Text(
"100,000",
style: TextStyle(
color: Colors.green, fontSize: 15),
),
title: Text("This is item $index"),
subtitle: Text('Electronics'),
);
}),
),
),
],
),
),
),
],
),
),
),
);
}
productSearchingField() {
return Container(
padding: EdgeInsets.fromLTRB(15, 10, 15, 0),
height: 60,
child: TextFormField(
controller: searchingInput,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Search Product or Barcode',
prefixIcon: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.search,
color: Colors.black54,
)),
),
),
);
}
}
Here i manage to do this using the below code hope it will work for you
class _DummyDesignState extends State<DummyDesign> {
List<String> ShoppingItems = ['Ball', 'Clet', 'JoyStick'];
List<String> PurchasedItem = [];
#override
Widget build(BuildContext context) {
print('List length is ${ShoppingItems.length}');
print('List length is ${PurchasedItem.length}');
return Scaffold(
appBar: AppBar(
title: Text('Hello'),
),
body: PurchasedItem.isEmpty
? Center(
child: Container(
height: MediaQuery.of(context).size.height * 0.2,
child: ListView.builder(
itemCount: ShoppingItems.length,
itemBuilder: (context, index) {
return ListTile(
onTap: (){
PurchasedItem.add(ShoppingItems[index]);
setState(() {
});
},
leading: Icon(Icons.list),
title: Text(
ShoppingItems[index],
style: TextStyle(color: Colors.green, fontSize: 15),
));
}),
),
)
: Center(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height * 0.4,
child: ListView.builder(
itemCount: PurchasedItem.length,
itemBuilder: (context, index) {
return Text(PurchasedItem[index]);
}),
),
Container(
height: MediaQuery.of(context).size.height * 0.4,
child: ListView.builder(
itemCount: ShoppingItems.length,
itemBuilder: (context, index) {
return ListTile(
onTap: (){
PurchasedItem.add(ShoppingItems[index]);
setState(() {
});
},
leading: Icon(Icons.list),
title: Text(
ShoppingItems[index],
style: TextStyle(color: Colors.green, fontSize: 15),
));
}),
),
],
),
),
));
}
}

Flutter: How to control a PageView by GetxController?

Subject: PageView and GetX
I'm having trouble detaching the controls on a PageView widget from the HomeView module. I have a GlobalController with its respective GlobalBinding that are instantiated when opening the HomeView. I would like to take the setPage(int page) method to the GlobalController that would eventually make the HomeView's PageView change pages. I don't know how to get PageController from PageView to GlobalController in order to make it work. How should I proceed?
Something Like this?
am using pageview in onboarding
class Onboard{
final headTitle;
final secondarytitle;
final discription;
final pngimage;
Onboardslist(this.headTitle, this.secondarytitle, this.discription, this.pngimage);
}
then for the controller
class OnboardController extends GetxController{
var selectedPagexNumber = 0.obs;
bool get isLastPage => selectedPagexNumber.value == onBoardPages.length -1;
var pageControll = PageController();
forwardAct()
{
if(isLastPage) Get.offNamedUntil(signin, (route)=> false);
else pageControll.nextPage(duration: 300.milliseconds, curve: Curves.ease);
}
List<Onboardslist> onBoardPages =
[
Onboardslist("title",
"short description",
"long description",
imageString),
Onboardslist("title",
"short description",
"long description",
imageString),
Onboardslist("title",
"short description",
"long description",
imageString),
Onboardslist("title",
"short description",
"long description",
imageString)
];
}
then for the view i did was simply like this
class Onboarding extends StatelessWidget {
final yourController= OnboardController();
#override
Widget build(BuildContext context) {
SizeXGet().init(context);
return Scaffold(
backgroundColor: decent_white,
appBar: AppBarCustom(
title: 'Skip',
button: ()=>Get.offNamedUntil(signin,(route)=>false),
),
body: WillPopScope(
onWillPop: () async => false,
child: SafeArea(
child: Stack(
children: [
PageView.builder(
controller: yourController.pageControll,
onPageChanged: yourController.selectedPagexNumber,
itemCount: yourController.onBoardPages.length,
itemBuilder: (context, index)
=>Padding(
padding: const EdgeInsets.only(left: 10,right: 10),
child: Container(
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: getHeight(150),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(left: 20,right: 20),
child: Text(yourController.onBoardPages[index].headTitle,
style: TextStyle(
color: darkish_color,
fontSize: getHeight(20),
fontFamily: 'Metropolis-SemiBold' ,
fontWeight: FontWeight.bold
),),
),
SizedBox(height: 15,),
Padding(
padding: const EdgeInsets.only(left: 50,right: 50),
child: Text(yourController.onBoardPages[index].secondarytitle,
style: TextStyle(
color: not_sopure_black,
fontSize: getHeight(26),
fontFamily: 'Metropolis-Bold' ,
fontWeight: FontWeight.bold
),
),
),
SizedBox(height: 15,),
Padding(
padding: const EdgeInsets.only(left: 40,right: 40),
child: Text(yourController.onBoardPages[index].discription,
style: TextStyle(
color: not_sopure_black,
fontSize: getHeight(15),
fontFamily: 'Metropolis-Regular' ,
),
),
),
],
),
),
SizedBox(height: 15,),
Image.asset(yourController.onBoardPages[index].pngimage),
],
),
),
),
),
),
],
),
),
),
bottomNavigationBar: BottomAppBar(
color: Colors.transparent,
elevation: 0,
child: Container(
height: 75,
width: MediaQuery.of(context).size.width,
child: Padding(
padding: const EdgeInsets.only(left: 25,right:25,),
child: Container(
width: MediaQuery.of(context).size.width,
child: Stack(
children: [
Align(
alignment: Alignment.centerLeft,
child: Container(
child: Row(
children: List.generate(yourController.onBoardPages.length,
(index)=>Obx(()=>
AnimatedContainer(
duration: Duration(milliseconds: 200),
margin: EdgeInsets.only(right: 5),
height: 10,
width: yourController.selectedPagexNumber.value == index ? 20 : 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(60),
color: yourController.selectedPagexNumber.value == index
? darkish_color
: not_sopure_black,),
),
)),
),
),
),
Align(
alignment: Alignment.centerRight,
child: Container(
width: 130,
height: 52,
child: RaisedButton(
elevation: 0,
onPressed: yourController.forwardAct,
splashColor: not_sopure_black,
color: darkish_color,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100)
),
child: Obx(() =>
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(yourController.isLastPage ? 'Next' : 'Next',
style: TextStyle(
color: Colors.white,
fontFamily: 'Metropolis-Semibold',
fontSize: 16,
),
),
],
),
),
),
),
)
],
),
),
),
),
),
);
}
}

Flutter ListView.builder() item click change UI data?

I want to increase the quantity when '+' icon se clicked and decrease the quantity when '-' icon is clicked in the ListView.builder(). But my code changes quantity of all listview items whichever icon I clicked. I'm new to Flutter and Dart. I want to change the data of particular row when user taps either '+' or '-' icon of that particular row.
Please help me to resolve my issue.
Here is my code -:
import 'package:flutter/material.dart';
import 'package:flutter_testing/InkWellGesture.dart';
class Cart extends StatefulWidget {
Cart({Key key}) : super(key: key);
#override
_CartState createState() => _CartState();
}
class _CartState extends State<Cart> {
int qty = 1;
int items = 2;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cart'),
),
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(
left: 3,
),
height: 60,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
elevation: 3,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 3, top: 7, right: 6),
width: 13,
height: 15,
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.green),
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Deliver to NAME address line 1...',
style: TextStyle(fontSize: 15)),
Text('click here to change address',
style: TextStyle(
fontSize: 12, color: Colors.grey)),
],
),
],
),
),
Icon(Icons.keyboard_arrow_right),
],
),
),
),
Expanded(
child: ListView.builder(
itemCount: items,
itemBuilder: (ctx, itemIndex) {
return Card(
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
child: Container(
height: 65,
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 5),
child: Row(
children: <Widget>[
Container(
width: 65,
height: 65,
decoration: BoxDecoration(
border:
Border.all(color: Colors.grey, width: 1),
borderRadius:
BorderRadius.all(Radius.circular(10))),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, right: 7),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Item Name',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold)),
Text(
'\u{20B9} 9,999',
style: TextStyle(fontSize: 18),
),
],
),
),
Padding(
padding: const EdgeInsets.only(right: 4),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
inkWellGesture(
() {
setState(() {
qty += 1;
});
},
child: Icon(
Icons.add_circle,
color: Colors.green,
size: 25,
),
),
Text(
qty > 0 ? qty.toString() : '1',
style: TextStyle(fontSize: 16),
),
inkWellGesture(
() {
setState(() {
qty -= 1;
});
},
child: Icon(
Icons.remove_circle,
color: Colors.red,
size: 25,
),
)
],
),
),
Expanded(
flex: 2,
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Icon(
Icons.delete_forever,
color: Colors.red,
size: 25,
),
],
),
)
],
),
),
],
),
),
],
),
),
);
}),
),
Container(
height: 200,
padding: const EdgeInsets.only(top: 15, left: 15, right: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Promo Code',
)),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Shipping'),
Text('Offer'),
Text('Tax'),
Text('Sub Total'),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(' \u{20B9} 80'),
Text('- \u{20B9} 100'),
Text(' \u{20B9} 1,799'),
Text(' \u{20B9} 8,200')
],
),
],
),
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity,
child: FlatButton(
child: Text('PROCEED TO \u{20B9} 10,019',
style: TextStyle(fontSize: 20)),
onPressed: () {},
color: Colors.green,
textColor: Colors.white,
))),
],
),
);
}
Here is the screenshot -:
Create an array of quantity having the same size that your items. Associate each item qty to the corresponding quantity array index.
int items = 2;
List<int> qties = [];
#override
void initState () {
for (int i = 0; i < items; ++ i) qties.add(1);
}
// ...
inkWellGesture(
() {
setState(() {
qties[itemIndex] += 1;
});
},
child: Icon(
Icons.add_circle,
color: Colors.green,
size: 25,
),
),
Text(
qties[itemIndex] > 0 ? qties[itemIndex].toString() : '1',
style: TextStyle(fontSize: 16),
),
inkWellGesture(
() {
setState(() {
qties[itemIndex] -= 1;
});
},
child: Icon(
Icons.remove_circle,
color: Colors.red,
size: 25,
),
),
All the values change because they all refer to the same qty variable. Each of your list item should have its own value. A way to do this would be to create a class containing all the data of your item.
class CardItem {
String name;
int qty;
String price;
// I've defined some default values but it could be anything else
CardItem({#required this.name, this.qty = 1, this.price = "9,999"});
}
Then you could generate a list of CardItem to build your ListView.
List<CardItem> _listItems = [];
int items = 2;
#override
void initState() {
super.initState();
for (int i = 0; i < items; i++) _listItems.add(CardItem(name: "Item Name $i", qty: 2));
}
// ...
// For the item name and price
Text(
_listItems[itemIndex].name,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Text(
'\u{20B9} ${_listItems[itemIndex].price}',
style: TextStyle(fontSize: 18),
),
// To add or remove
inkWellGesture(
() {
setState(() => _listItems[itemIndex].qty += 1);
},
child: Icon(
Icons.add_circle,
color: Colors.green,
size: 25,
),
),
Text(
_listItems[itemIndex].qty > 0 ? _listItems[itemIndex].qty.toString() : '1',
style: TextStyle(fontSize: 16),
),
inkWellGesture(
() {
setState(() => _listItems[itemIndex].qty -= 1);
},
child: Icon(
Icons.remove_circle,
color: Colors.red,
size: 25,
),
),
Make sure you're getting the item's quantity by its index (itemBuilder: (ctx, itemIndex)). Try this:
Expanded(
child: ListView.builder(
itemCount: items,
itemBuilder: (ctx, itemIndex) {
return Card(
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
child: Container(
height: 65,
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 5),
child: Row(
children: <Widget>[
Container(
width: 65,
height: 65,
decoration: BoxDecoration(
border:
Border.all(color: Colors.grey, width: 1),
borderRadius:
BorderRadius.all(Radius.circular(10))),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, right: 7),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(items[itemIndex].name,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold)),
Text(
'\u{20B9} ${items[itemIndex].amount}',
style: TextStyle(fontSize: 18),
),
],
),
),
Padding(
padding: const EdgeInsets.only(right: 4),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
inkWellGesture(
() {
setState(() {
items[itemIndex].quantity += 1;
});
},
child: Icon(
Icons.add_circle,
color: Colors.green,
size: 25,
),
),
Text(
items[itemIndex].quantity > 0 ? items[itemIndex].quantity.toString() : '1',
style: TextStyle(fontSize: 16),
),
inkWellGesture(
() {
setState(() {
items[itemIndex].quantity -= 1;
});
},
child: Icon(
Icons.remove_circle,
color: Colors.red,
size: 25,
),
)
],
),
),
Expanded(
flex: 2,
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Icon(
Icons.delete_forever,
color: Colors.red,
size: 25,
),
],
),
)
],
),
),
],
),
),
],
),
),
);
}),
),

Bug when using Offlinebuilder in Liquidswipe

Hello I am using Offlinebuilder and Liquidswipe but it gives me a strange error someone knows how I can fix? thank you very much!
ERROR:
You should specify either a builder or a child
'package:flutter_offline/src/main.dart':
Failed assertion: line 41 pos 16: '!(builder is WidgetBuilder && child is Widget) && !(builder == null && child == null)'
class Luz extends State<MyApp> {
...
Widget build(BuildContext context) {
pages(bool connected) => [
//pagina1
Container(
...
),
Container(
color: Colors.pinkAccent[400],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 5,
child: Align(
child: AnimatedContainer(
alignment: Alignment(0, 0.3),
duration: Duration(milliseconds: 600),
child: AnimatedContainer(
width: 135,
height: 135,
color: Colors.transparent,
duration: Duration(milliseconds: 1250),
curve: Curves.bounceOut,
child: GestureDetector(
onTap: () async {
...
},
child: Container(
decoration: BoxDecoration(
color:Colors.purple[700].withOpacity(0.90),
borderRadius: BorderRadius.circular(40),
boxShadow: [
BoxShadow(
color: Colors.white,
spreadRadius: 4,
blurRadius: 50,
offset: Offset(0, 0),
),
],
),
),
),
),
),
),
),
Expanded(
flex: 5,
child: Stack(
children: <Widget>[
Positioned(
left: 8,
right: 8,
top: 0,
child: Align(
alignment: Alignment(0, -0.3),
child: Container(
width: 250,
height: 250,
child: (
Text(
'Luz desligada',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 28,
color: Colors.white,
),
)
),
),
),
),
],
),
),
Container(
color: Colors.transparent,
child: ClipPath(
clipper: WaveClipperOne(flip: true, reverse: true),
child: Container(
height: 120,
color: Colors.limeAccent[400],
),
),
),
Positioned(
left: 35,
right: 35,
top: connected ? -1000 : 175,
child: GestureDetector(
/*onTap: () async {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeftWithFade,
child: MyApp()
)
);
},*/
child: Container(
height: 500,
width: 250,
color: Colors.transparent,
child:Center(
child: Container(
width: 250,
height: 111,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(25),
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(27, 32, 27, 0),
child: Text(
'SEM INTERNET',
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.bold,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(25, 1, 25, 30),
child: Text(
'RECONNECTCE',
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.bold,
),
),
),
],
),
),
),
),
),
),
Column(
children: <Widget>[
Text(''),
],
),
],
),
),
];
return Scaffold(
body: OfflineBuilder(
connectivityBuilder: (
BuildContext context,
ConnectivityResult connectivity,
Widget Container,
) {
final bool connected = connectivity != ConnectivityResult.none;
return LiquidSwipe(
pages: pages(connected),
enableLoop: true,
fullTransitionValue: 700,
enableSlideIcon: false,
waveType: WaveType.liquidReveal,
positionSlideIcon: 0.7,
);
},
),
);
}
}
You can copy paste run full code below
Step 1: change Widget Container to Widget child
Step 2: You can use builder of OfflineBuilder and use Stack in connectivityBuilder
code snippet
bool connected;
return MaterialApp(
home: Scaffold(
body: OfflineBuilder(
connectivityBuilder: (
BuildContext context,
ConnectivityResult connectivity,
Widget child,
) {
connected = connectivity != ConnectivityResult.none;
print(connected);
return Stack(
fit: StackFit.expand,
children: [
child,
Positioned(
height: 32.0,
left: 0.0,
right: 0.0,
child: AnimatedContainer(
duration: const Duration(milliseconds: 350),
color: connected ? Color(0xFF00EE44) : Color(0xFFEE4400),
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 350),
child: connected
? Text('ONLINE')
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('OFFLINE'),
SizedBox(width: 8.0),
SizedBox(
width: 12.0,
height: 12.0,
child: CircularProgressIndicator(
strokeWidth: 2.0,
valueColor:
AlwaysStoppedAnimation<Color>(Colors.white),
),
),
],
),
),
),
),
],
);
},
builder: (BuildContext context) {
return LiquidSwipe(
pages: pages(connected),
fullTransitionValue: 200,
enableSlideIcon: true,
enableLoop: true,
positionSlideIcon: 0.5,
currentUpdateTypeCallback: updateTypeCallback,
waveType: WaveType.liquidReveal,
);
},
)));
working demo
full code
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:liquid_swipe/liquid_swipe.dart';
import 'package:flutter_offline/flutter_offline.dart';
void main() {
runApp(
MyApp(),
);
}
class MyApp extends StatefulWidget {
static final style = TextStyle(
fontSize: 30,
fontFamily: "Billy",
fontWeight: FontWeight.w600,
);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int page = 0;
UpdateType updateType;
List<Container> pages(bool connected) => [
Container(
color: Colors.pink,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Image.network(
'https://picsum.photos/500?image=14',
fit: BoxFit.cover,
),
Padding(
padding: EdgeInsets.all(20.0),
),
Column(
children: <Widget>[
Text(
"Hi",
style: MyApp.style,
),
Text(
"It's Me",
style: MyApp.style,
),
Text(
"Sahdeep",
style: MyApp.style,
),
],
),
],
),
),
Container(
color: Colors.deepPurpleAccent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Image.network(
'https://picsum.photos/500?image=13',
fit: BoxFit.cover,
),
Padding(
padding: EdgeInsets.all(20.0),
),
Column(
children: <Widget>[
Text(
"Take a",
style: MyApp.style,
),
Text(
"look at",
style: MyApp.style,
),
Text(
"Liquid Swipe",
style: MyApp.style,
),
],
),
],
),
),
Container(
color: Colors.greenAccent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Image.network(
'https://picsum.photos/500?image=11',
fit: BoxFit.cover,
),
Padding(
padding: EdgeInsets.all(20.0),
),
Column(
children: <Widget>[
Text(
"Liked?",
style: MyApp.style,
),
Text(
"Fork!",
style: MyApp.style,
),
Text(
"Give Star!",
style: MyApp.style,
),
],
),
],
),
),
Container(
color: Colors.yellowAccent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Image.network(
'https://picsum.photos/500?image=9',
fit: BoxFit.cover,
),
Padding(
padding: EdgeInsets.all(20.0),
),
Column(
children: <Widget>[
Text(
"Can be",
style: MyApp.style,
),
Text(
"Used for",
style: MyApp.style,
),
Text(
"Onboarding Design",
style: MyApp.style,
),
],
),
],
),
),
Container(
color: Colors.redAccent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Image.network(
'https://picsum.photos/500?image=10',
fit: BoxFit.cover,
),
Padding(
padding: EdgeInsets.all(20.0),
),
Column(
children: <Widget>[
Text(
"Do",
style: MyApp.style,
),
Text(
"Try it",
style: MyApp.style,
),
Text(
"Thank You",
style: MyApp.style,
),
],
),
],
),
),
];
Widget _buildDot(int index) {
double selectedness = Curves.easeOut.transform(
max(
0.0,
1.0 - ((page ?? 0) - index).abs(),
),
);
double zoom = 1.0 + (2.0 - 1.0) * selectedness;
return Container(
width: 25.0,
child: Center(
child: Material(
color: Colors.white,
type: MaterialType.circle,
child: Container(
width: 8.0 * zoom,
height: 8.0 * zoom,
),
),
),
);
}
bool connected;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: OfflineBuilder(
connectivityBuilder: (
BuildContext context,
ConnectivityResult connectivity,
Widget child,
) {
connected = connectivity != ConnectivityResult.none;
print(connected);
return Stack(
fit: StackFit.expand,
children: [
child,
Positioned(
height: 32.0,
left: 0.0,
right: 0.0,
child: AnimatedContainer(
duration: const Duration(milliseconds: 350),
color: connected ? Color(0xFF00EE44) : Color(0xFFEE4400),
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 350),
child: connected
? Text('ONLINE')
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('OFFLINE'),
SizedBox(width: 8.0),
SizedBox(
width: 12.0,
height: 12.0,
child: CircularProgressIndicator(
strokeWidth: 2.0,
valueColor:
AlwaysStoppedAnimation<Color>(Colors.white),
),
),
],
),
),
),
),
],
);
},
builder: (BuildContext context) {
return LiquidSwipe(
pages: pages(connected),
fullTransitionValue: 200,
enableSlideIcon: true,
enableLoop: true,
positionSlideIcon: 0.5,
currentUpdateTypeCallback: updateTypeCallback,
waveType: WaveType.liquidReveal,
);
},
)));
}
updateTypeCallback(UpdateType updateType) {
print(updateType);
}
}

flutter sliver list tabbar bottom overflowed error

I am a newbie of flutter.
I have just started to rebuild my android app built by Kotlin to flutter.
However, I am stuck in building the user page.
I intended to build the page like this screenshot
However, I continuously get bottom overflowed error.
How can I solve this problem?
I am looking forward to your help.
I will attach the whole code of the page.
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;
#override
void initState() {
super.initState();
_controller = new TabController(length: 2, vsync: this);
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder: (context, isScrolled) {
return <Widget> [
SliverList(
// itemExtent: 300,
delegate: SliverChildListDelegate([
Container(
child: Column(
children: <Widget>[
_detailedBody()
],
),
)
]),
),
];
},
body: 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: 90,
padding: EdgeInsets.only(top: 20),
child: Tab(
icon: const Icon(Icons.home,
),
text: 'PLANTS',
),
),
Container(
height: 90,
padding: EdgeInsets.only(top: 20),
child: Tab(
icon: const Icon(Icons.bookmark_border,
),
text: 'BOOKMARK',
),
)
],
),
Expanded(
flex: 1,
child: TabBarView(
controller: _controller,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: <Widget>[
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: () => {
},
),
),
],
),
),
Expanded(
child: 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,
),
),
),
),
],
),
),
Container(
child: 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 SafeArea(
child: 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),
),
],
)
],
)
],
),
),
],
),
);
}
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',
];
Future<void> signOutWithGoogle() async {
// Sign out with firebase
await _Auth.signOut();
// Sign out with google
await _googleSignIn.signOut();
}
}