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),
));
}),
),
],
),
),
));
}
}
Related
i have Provider model:
class TerminalDataModel with ChangeNotifier{
List<Item> _itemMenu = listItems;
final List<Order> _ordersList = orders;
Order? _currentOrder;
Order? get currentOrder => _currentOrder;
List<Order> get ordersList => _ordersList;
void createOrder() {
_currentOrder = Order(
user: currentUser?.name,
number: 1,
orderStatus: OrderStatus.opened,
time: DateTime.now());
_ordersList.add(_currentOrder!);
notifyListeners();
}
void changeOrder(Order order){
}
}
and two pages: 1. terminal page: on this page I can view my selected order and can change it or change status(paid or for example closed)
class OrderList extends StatelessWidget {
TerminalDataModel terminalDataModel = TerminalDataModel();
OrderList({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: ChangeNotifierProvider<TerminalDataModel>.value(
value: terminalDataModel,
child: OrdersTableView(),
));
}
}
class OrdersTableView extends StatelessWidget {
List<GlobalKey> _key = List.generate(3, (v) => new GlobalKey());
double yPosition = 170;
var provider;
OrdersTableView({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
provider = Provider.of<TerminalDataModel>(context, listen: true);
GlobalKey key = GlobalKey();
return Column(
children: [
Stack(
children: [
Container(
height: 40,
color: Styles.appBarColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
Container(
height: double.infinity,
width: 50,
color: Styles.blackColor,
child: IconButton(
onPressed: () {
Navigator.pushNamed(context, '/terminal');
},
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
)),
Row(
children: [
Text(currentUser?.name ?? '',
style: const TextStyle(
color: Colors.white, fontSize: 18)),
const Icon(
Icons.lock,
color: Colors.white,
),
],
),
],
),
),
SizedBox(
height: 40,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Center(
child: Text('Orders',
style: TextStyle(color: Colors.white, fontSize: 18))),
],
),
),
],
),
Stack(children: [
Container(
height: 50,
width: MediaQuery.of(context).size.width,
color: Styles.blackColor,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
ElevatedButton(
onPressed: () {
Provider.of<TerminalDataModel>(context, listen: false)
.createOrder();
},
child: const Text("New order",
style: TextStyle(color: Colors.white, fontSize: 18)),
),
const SizedBox(
width: 25,
),
TextButton(
key: _key[0],
onPressed: () {},
child: const Text('All Status',
style: const TextStyle(
color: Colors.white, fontSize: 18))),
const SizedBox(
width: 25,
),
TextButton(
key: _key[1],
onPressed: () {},
child: const Text('Wait pay',
style: TextStyle(color: Colors.white, fontSize: 18))),
const SizedBox(
width: 25,
),
TextButton(
key: _key[2],
onPressed: () {},
child: const Text('Payed',
style: TextStyle(color: Colors.white, fontSize: 18))),
],
),
),
),
Positioned(
bottom: -22,
left: yPosition,
child: const Icon(
Icons.arrow_drop_up,
size: 50,
color: Colors.white,
))
]),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: SizedBox(
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Expanded(
flex: 3,
child: Text('Open',
style: TextStyle(color: Colors.black, fontSize: 18))),
Expanded(
flex: 5,
child: Text('Order',
style: TextStyle(color: Colors.black, fontSize: 18))),
Expanded(
flex: 3,
child: Text('Status',
style: TextStyle(color: Colors.black, fontSize: 18))),
Expanded(
flex: 1,
child: Text('Sum',
style: TextStyle(color: Colors.black, fontSize: 18))),
],
),
),
),
const Divider(),
ordersList(provider.ordersList, context),
],
);
}
double getYPositionOfWidget(
GlobalKey key,
) {
RenderBox box = key.currentContext?.findRenderObject() as RenderBox;
Offset position = box.localToGlobal(Offset.zero); //this is global position
double y = position.dy;
return y;
}
Widget ordersList(List<Order> orderList, BuildContext context) {
Column ordersTable = Column(
children: <Widget>[],
);
for (int i = 0; i <= orderList.length - 1; i++) {
ordersTable.children.add(
GestureDetector(
onTap: () {
//Navigator.pushNamed(context, '/terminal',arguments: {'model': provider });
Navigator.push(context, MaterialPageRoute(builder: (contex) {
return Provider<TerminalDataModel>.value(
value: provider, child: PosTerminal());
}));
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: SizedBox(
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 3,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${orderList[i].time!.hour}:${orderList[i].time!.minute}",
style: const TextStyle(
color: Colors.black, fontSize: 18)),
Text(getTimeAgo(orderList[i].time ?? DateTime.now()),
style: const TextStyle(
color: Colors.black, fontSize: 13))
],
)),
const Expanded(
flex: 5,
child: Text('Order',
style: TextStyle(color: Colors.black, fontSize: 18))),
const Expanded(
flex: 3,
child: Text('Status',
style: TextStyle(color: Colors.black, fontSize: 18))),
const Expanded(
flex: 1,
child: Text('Sum',
style: TextStyle(color: Colors.black, fontSize: 18))),
],
),
),
),
),
);
ordersTable.children.add(const Divider());
}
return ordersTable;
}
String getTimeAgo(DateTime dateTime) {
String timeAgo = '';
if (dateTime.hour < DateTime.now().hour) {
timeAgo += "${DateTime.now().hour - dateTime.hour} hours, ";
}
if (dateTime.minute < DateTime.now().minute) {
timeAgo += "${DateTime.now().minute - dateTime.minute} minutes";
}
return timeAgo;
}
}
and 2. order_detale page: there I show a list of orders and can create a new order
class PosTerminal extends StatelessWidget {
PosTerminal({Key? key, }) : super(key: key);
#override
Widget build(BuildContext context) {
print(Provider.of<TerminalDataModel>(context,listen: false).ordersList);
return Scaffold(
backgroundColor: Styles.backgroundColor,
body: ChangeNotifierProvider(
create: (context) => TerminalDataModel(),
child: const PosBody(),
)
);
}
}
class PosBody extends StatelessWidget {
const PosBody({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
double sizeW = MediaQuery.of(context).size.width;
double appBarH = 35;
return Column(
children: [
SizedBox(
width: sizeW,
height: appBarH,
child: Stack(children: [
SizedBox(
width: sizeW,
height: appBarH,
child: Container(
color: Styles.appBarColor,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
ElevatedButton.icon(
onPressed: () {
Navigator.pushNamed(context, '/orders');
},
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
label: Text(AppLocalizations.of(context)!.orders,
style: const TextStyle(
color: Colors.white, fontSize: 18)),
style: ElevatedButton.styleFrom(
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
/* Please add this to avoid padding */
elevation: 0,
primary: Colors.transparent,
),
),
SizedBox(
height: appBarH - 3,
width: 100,
child: ElevatedButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Styles.backgroundColor),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(4),
topRight: Radius.circular(4),
))),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
elevation: MaterialStateProperty.all(0),
),
child: Text(
AppLocalizations.of(context)!.order,
style: const TextStyle(
color: Colors.black, fontSize: 18),
),
),
),
],
),
Row(
children: [
const Text("Сергей",
style:
TextStyle(color: Colors.white, fontSize: 18)),
const SizedBox(
width: 5,
),
const Icon(
Icons.lock,
color: Colors.white,
),
ElevatedButton.icon(
onPressed: () {
final action = CupertinoActionSheet(
actions: <Widget>[
CupertinoActionSheetAction(
child: const Text(
"Admin panel",
style:
TextStyle(color: Styles.appBarColor),
),
onPressed: () {
Navigator.pushNamed(
context, '/adminPanel');
},
),
CupertinoActionSheetAction(
child: const Text("Settings",
style: TextStyle(
color: Styles.appBarColor)),
onPressed: () {},
)
],
cancelButton: CupertinoActionSheetAction(
child: const Text(
"Cancel",
style: TextStyle(color: Colors.red),
),
onPressed: () {
Navigator.pop(context);
},
),
);
showCupertinoModalPopup(
context: context,
builder: (context) => action);
},
icon: const Icon(Icons.menu),
label: const Text(""),
style: ElevatedButton.styleFrom(
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
/* Please add this to avoid padding */
elevation: 0,
primary: Colors.transparent,
),
),
],
)
],
),
),
),
SizedBox(
width: sizeW,
height: appBarH,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text("Чек № 2323",
style: TextStyle(color: Colors.white, fontSize: 18)),
],
),
),
]),
),
SizedBox(
height: MediaQuery.of(context).size.height - appBarH,
child: Row(
children: [
Expanded(
flex: 2,
child: Container(
color: Styles.backgroundColor,
child: Column(
children: [
const SizedBox(
height: 25,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Expanded(flex: 4, child: Text("Наименование")),
Expanded(flex: 1, child: Text("Кол-во")),
Expanded(flex: 1, child: Text("Цена")),
Expanded(flex: 1, child: Text("Итого")),
],
),
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 15.0),
child: Divider(
height: 1,
color: Colors.black12,
),
),
SizedBox(
height: MediaQuery.of(context).size.height -
appBarH -
200,
child: Container(),
),
const Divider(
height: 1,
color: Colors.black12,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 25, vertical: 10),
child: Column(
children: [
Row(
children: const [
Text("Итого"),
],
),
const SizedBox(
height: 10,
),
Row(
children: const [
Text("К оплате"),
],
),
Padding(
padding:
const EdgeInsets.symmetric(vertical: 15),
child: SizedBox(
height: 30,
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green,
),
onPressed: () {},
child: const Text("Pay")),
),
)
],
)),
],
),
),
),
Expanded(
flex: 4,
child: Container(
color: Colors.white,
),
),
],
),
)
],
);
}
}
On the model, I save my orders and when I tap on the order I want to pass an object to the 2nd-page, update it and when I pop my 2nd-page list of orders should be updated. How I can do it?
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,
),
),
],
),
),
),
),
)
],
),
),
),
),
),
);
}
}
class CardContent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(8.0),
height: 40,
child: Card(
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Test Campaign',
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
),
),
LineButton(
onPress: () => null,
label: 'View',
height: 30,
backgroundColor: Colors.grey[300],
)
],
),
),
],
),
),
);
}
}
I have this piece of code that outputs this. Now this part it's only the content inside the tabs.
As you can see the Card goes all the way down. I want that Card to be about 50 pixel in height. How can I achieve that?
You just wrap your container just sniglechildScrollView.
SingleChildScrollView(
padding: EdgeInsets.all(8),
child: Column(
children: [
Container(
margin: const EdgeInsets.all(8.0),
height: 80,
child: Card(
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Test Campaign',
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
),
),
LineButton(
onPress: () => null,
label: 'View',
height: 30,
backgroundColor: Colors.grey[300],
)
],
),
),
],
),
),
),
],
),
)
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,
),
],
),
)
],
),
),
],
),
),
],
),
),
);
}),
),
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
Container(
color:Colors.blueGrey.shade900,
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.15,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text("Available Balance ₹ 10050", style: TextStyle(
color: Colors.white,
fontSize: 18,
),),
],),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
RaisedButton(onPressed: () {}, color: Colors.teal, child: Text("Recharge", style: TextStyle(
color: Colors.white
),),),
RaisedButton(onPressed: () {}, color: Colors.teal, child: Text("Read Rule", style: TextStyle(
color: Colors.white
),),),
Icon(Icons.refresh_rounded, color: Colors.white,)
],),
),
SizedBox(
height: 5,
),
// I need to insert the tabBarHere
],
),
),
],
),
),
);
I have created the widget from flutter but i am not able to display the TabBar after this Widget. I have seen the basic method to create the tabs using DefaultTabController() but it is working when we are using in the bottom of the appbar
You can use a NestedScrollView:
Scaffold(
body: SafeArea(
child: DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxScrolled) {
return <Widget>[
SliverToBoxAdapter(
child: Container(
color: Colors.blueGrey.shade900,
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.15,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
"Available Balance ₹ 10050",
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
RaisedButton(
onPressed: () {},
color: Colors.teal,
child: Text(
"Recharge",
style: TextStyle(color: Colors.white),
),
),
RaisedButton(
onPressed: () {},
color: Colors.teal,
child: Text(
"Read Rule",
style: TextStyle(color: Colors.white),
),
),
Icon(
Icons.refresh,
color: Colors.white,
)
],
),
),
SizedBox(
height: 5,
),
],
),
),
),
SliverToBoxAdapter(
child: Container(
color: Colors.blueGrey.shade900,
child: TabBar(
tabs: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: Icon(Icons.card_giftcard),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: Icon(Icons.store),
),
],
),
),
),
];
},
body: Column(
children: <Widget>[
Flexible(
child: TabBarView(
children: [
Center(child: Text('tab 1')),
Center(child: Text('tab 2')),
],
),
),
],
),
),
),
)
)
Result:
you can use bottomNavigationBar
class _MyHomePageState extends State<MyHomePage> {
var selectedIndex = 0;
void onItemTapped(int index) {
setState(() {
selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("data"),
backgroundColor: Colors.blueGrey.shade900,
actions: <Widget>[Icon(Icons.notifications)],
),
drawer: Drawer(),
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.amber,
elevation: 12.0,
type: BottomNavigationBarType.shifting,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.store), title: Text('Home')),
BottomNavigationBarItem(
icon: Icon(Icons.warning), title: Text('Warning')),
],
showUnselectedLabels: true,
currentIndex: selectedIndex,
unselectedItemColor: Colors.white,
fixedColor: Colors.teal,
onTap: onItemTapped,
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
color: Colors.blueGrey.shade900,
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.15,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
"Available Balance ₹ 10050",
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
RaisedButton(
onPressed: () {},
color: Colors.teal,
child: Text(
"Recharge",
style: TextStyle(color: Colors.white),
),
),
RaisedButton(
onPressed: () {},
color: Colors.teal,
child: Text(
"Read Rule",
style: TextStyle(color: Colors.white),
),
),
Icon(
Icons.refresh,
color: Colors.white,
)
],
),
),
SizedBox(
height: 5,
),
// I need to insert the tabBarHere
],
),
),
],
),
),
);
}