Flutter: How to control a PageView by GetxController? - flutter

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,
),
),
],
),
),
),
),
)
],
),
),
),
),
),
);
}
}

Related

Flutter SliverAppBar add widget to collapsed part

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: () {},
)
],
),
)),
)
]),
),
],
),

ListView.builder is not scrolling in flutter

i'm trying to integrate a listView.builder in my UI! First of all, the whole content of the screen is inside a CustomScrollView that has silver widgets inside of it. Everything works pretty fine unless that my listview is not scrolling.
Here is the code:
class _DashboardScreenState extends State<DashboardScreen> {
#override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
return Scaffold(
appBar: CustomAppBar(),
body: CustomScrollView(
physics: ClampingScrollPhysics(),
slivers: <Widget>[
_buildHeader(screenHeight),
_buildBody(screenHeight),
],
),
);
}
}
The _buildBody code:
SliverToBoxAdapter _buildBody(double screenHeight) {
return SliverToBoxAdapter(
child: Column(
children: [
Container(
width: 100,
height: 65,
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: ElevatedButton(
onPressed: () {},
child: Text(
'Add',
style: TextStyle(fontSize: 18),
),
style: ElevatedButton.styleFrom(
shape: StadiumBorder(),
backgroundColor: Palette.primaryColor),
),
),
),
SizedBox(
height: 10,
),
ListView.builder(
scrollDirection: Axis.vertical,
physics: const AlwaysScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: 6,
itemBuilder: ((BuildContext context, int index) {
return Container(
margin: const EdgeInsets.symmetric(
vertical: 10.0,
horizontal: 20.0,
),
padding: const EdgeInsets.all(10.0),
height: screenHeight * 0.15,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFFAD9FE4), Palette.primaryColor],
),
borderRadius: BorderRadius.circular(20.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Image.asset(
"assets/worker.png",
height: 80,
width: 80,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Somme: 50 €',
style: const TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: screenHeight * 0.01),
Text(
'Date: 19 novembre 2022',
style: TextStyle(fontSize: 10, color: Colors.white),
),
SizedBox(height: screenHeight * 0.01),
Text(
'Follow the instructions\nto do your own test.',
style: const TextStyle(
color: Colors.white,
fontSize: 16.0,
),
maxLines: 2,
),
],
)
],
),
);
}))
],
),
);
}
I tried adding shrinkWrap: true as well as the scroll direction. Also tried wrapping it inside a SingleScrollChildView, none of the solutions worked for me. I appreciate any kind of help!
You can use physics: const NeverScrollableScrollPhysics(), on listView, the parent widget is already handling the scroll event. But you can replace listView with Column widget.(we already have on parent, therefor using loop)
SliverToBoxAdapter _buildBody(double screenHeight) {
return SliverToBoxAdapter(
child: Column(
children: [
Container(
width: 100,
height: 65,
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: ElevatedButton(
onPressed: () {},
child: Text(
'Add',
style: TextStyle(fontSize: 18),
),
style: ElevatedButton.styleFrom(
shape: StadiumBorder(),
backgroundColor: Palette.primaryColor),
),
),
),
SizedBox(
height: 10,
),
for (int i = 0; i < 6; i++)
Container(
margin: const EdgeInsets.symmetric(
vertical: 10.0,
horizontal: 20.0,
),
padding: const EdgeInsets.all(10.0),
height: screenHeight * 0.15,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFFAD9FE4), Palette.primaryColor],
),
borderRadius: BorderRadius.circular(20.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Image.asset(
"assets/worker.png",
height: 80,
width: 80,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Somme: 50 €',
style: const TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: screenHeight * 0.01),
Text(
'Date: 19 novembre 2022',
style: TextStyle(fontSize: 10, color: Colors.white),
),
SizedBox(height: screenHeight * 0.01),
Text(
'Follow the instructions\nto do your own test.',
style: const TextStyle(
color: Colors.white,
fontSize: 16.0,
),
maxLines: 2,
),
],
)
],
),
)
],
),
);
}
Instead of using ListView.Builderinside CustomScrollView. It is always better to use Slivers. Therefore, instead of wrapping ListView.builder with SliverToBoxAdapter, use SliverList. Here is the detail code I have refactored below for you. Or you can directly visit this link where you can play with the refactored code.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
home: const DashboardScreen(),
debugShowCheckedModeBanner: false,
);
}
}
class DashboardScreen extends StatefulWidget {
const DashboardScreen({super.key});
#override
State<DashboardScreen> createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen> {
#override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(),
body: CustomScrollView(
physics: ClampingScrollPhysics(),
slivers: <Widget>[
// your build header widget
SliverToBoxAdapter(
child: Container(
width: 100,
height: 65,
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: ElevatedButton(
onPressed: () {},
child: Text(
'Add',
style: TextStyle(fontSize: 18),
),
style: ElevatedButton.styleFrom(
shape: StadiumBorder(),
backgroundColor: Colors.red,
),
),
),
),
),
SliverToBoxAdapter(
child: SizedBox(height: 10),
),
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return Container(
margin: const EdgeInsets.symmetric(
vertical: 10.0,
horizontal: 20.0,
),
padding: const EdgeInsets.all(10.0),
height: screenHeight * 0.15,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFFAD9FE4), Colors.red],
),
borderRadius: BorderRadius.circular(20.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
// Image.asset(
// "assets/worker.png",
// height: 80,
// width: 80,
// ),
//
Container(
height: 80,
width: 80,
child: Text("A"),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Somme: 50 €',
style: const TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: screenHeight * 0.01),
Text(
'Date: 19 novembre 2022',
style: TextStyle(fontSize: 10, color: Colors.white),
),
SizedBox(height: screenHeight * 0.01),
Text(
'Follow the instructions\nto do your own test.',
style: const TextStyle(
color: Colors.white,
fontSize: 16.0,
),
maxLines: 2,
),
],
)
],
),
);
}),
)
],
),
);
}
}

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),
));
}),
),
],
),
),
));
}
}

How to refresh Alert Dialog without closing it in Flutter

I am having an issue while changing the value in the alert dialog box in flutter. I want to change value of it without closing alert box
you can use like this
dialoge(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
scrollable: true,
contentPadding: EdgeInsets.all(5),
title: Center(
child: Text(
'Product Detail',
style: TextStyle(
color: yellowColor,
),
)),
content: shownecklace(selectedpp: selectedpp),
);
});
}
Make alert dialogue uge box within a stateful widget
class shownecklace extends StatefulWidget {
int selectedpp;
shownecklace({Key? key, required this.selectedpp}) : super(key: key);
#override
_shownecklaceState createState() => _shownecklaceState();
}
class _shownecklaceState extends State<shownecklace> {
#override
Widget build(BuildContext context) {
return Container(
width: 675,
height: 475,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: blackColor,
),
height: 460,
child: PageView.builder(
itemCount: ProductDetailsModel.productDetailsList.length,
controller: PageController(initialPage: widget.selectedpp, keepPage: true, viewportFraction: 1),
itemBuilder: (BuildContext context, int index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(height: 10),
Container(
height: 370,
width: double.infinity,
child: PinchZoom(
resetDuration: const Duration(milliseconds: 4000),
maxScale: 2.9,
onZoomStart: () {
print('Start zooming');
},
onZoomEnd: () {
print('Stop zooming');
},
child: Image.network(ProductDetailsModel.productDetailsList[index].itemImg.toString(),
fit: BoxFit.cover, height: 270, width: double.infinity)),
),
SizedBox(
height: 10,
),
Padding(
padding: const EdgeInsets.only(left: 10.0, right: 12),
child: Container(
width: 250,
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Product Name :",
style: TextStyle(
fontSize: 14,
color: yellowColor,
),
),
Text(
ProductDetailsModel.productDetailsList[index].itemName.toString(),
style: TextStyle(fontSize: 14, color: yellowColor),
)
],
),
SizedBox(
height: 10,
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Tag No :",
style: TextStyle(
fontSize: 14,
color: yellowColor,
),
),
Text(
ProductDetailsModel.productDetailsList[index].tagNo.toString(),
style: TextStyle(
fontSize: 14,
color: yellowColor,
),
)
],
),
SizedBox(
height: 10,
),
],
),
),
),
],
);
},
),
),
),
SizedBox(
height: 10,
),
],
),
);
}
}

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();
}
}