Related
This is my code where I am showing list of pending invoices.But when i accept the it should reload the pending invoice widget after clicking on snack bar action button.When user clicks on accept button its showing snack bar and when pressed accept action button snack bar it navigate back to same widget where I needs to update that widget along with new list of pending invoices without the invoice which we have accepted
class PendingInvoiceWidget extends StatelessWidget {
final double maxWidth;
final double maxHeight;
final bool isOverdue;
final String amount;
final String savedAmount;
final String invoiceDate;
final String dueDate;
Invoice fullDetails;
int index;
bool userConsentGiven = false;
final String companyName;
PendingInvoiceWidget(
{required this.fullDetails,
required this.maxWidth,
required this.maxHeight,
required this.amount,
required this.savedAmount,
required this.index,
required this.invoiceDate,
required this.dueDate,
required this.companyName,
required this.isOverdue});
#override
Widget build(BuildContext context) {
TextEditingController acceptController = TextEditingController();
TextEditingController rejectController = TextEditingController();
List<Invoice> pendingInvoice =
Provider.of<TransactionManager>(context).pendingInvoice;
String? invoiceId = fullDetails.sId;
String invAmt = double.parse(amount).toStringAsFixed(2);
DateTime id = DateTime.parse(invoiceDate);
DateTime dd = DateTime.parse(dueDate);
DateTime currentDate = DateTime.now();
Duration dif = dd.difference(currentDate);
int daysLeft = dif.inDays;
String idueDate = DateFormat("dd-MMM-yyyy").format(dd);
String invDate = DateFormat("dd-MMM-yyyy").format(id);
double h1p = maxHeight * 0.01;
double h10p = maxHeight * 0.1;
double w10p = maxWidth * 0.1;
return ProgressHUD(child: Builder(builder: (context) {
final progress = ProgressHUD.of(context);
return ExpandableNotifier(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: w10p * .5, vertical: 10),
child: Expandable(
collapsed: ExpandableButton(
child: Card(
child: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colours.offWhite,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
isOverdue
? Padding(
padding: EdgeInsets.symmetric(
vertical: h1p * 1),
child: Container(
// height: h1p * 4.5,
// width: w10p * 1.7,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(5),
color: Colours.failPrimary,
),
child: const Center(
child: Padding(
padding: EdgeInsets.all(4),
child: Text(
"Overdue",
style: TextStyles.overdue,
),
),
),
),
)
: Container(),
Row(
children: [
Text(
"${fullDetails.invoiceNumber}",
style: TextStyles.textStyle6,
),
SvgPicture.asset(
"assets/images/home_images/arrow-circle-right.svg"),
],
),
expanded: Column(
children: [
ExpandableButton(
child: Card(
child: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colours.offWhite,
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
isOverdue
? Text(
"$daysLeft days Overdue",
style: TextStyles.textStyle57,
)
: Text(
"$daysLeft days left",
style: TextStyles.textStyle57,
),
Text(
"₹ $invAmt",
style: TextStyles.textStyle58,
),
],
)
]),
),
),
),
Card(
elevation: .5,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 4,
),
const Text(
"Invoice Date",
style: TextStyles.textStyle62,
),
Text(
invDate,
style: TextStyles.textStyle63,
),
// Text(
// companyName,
// style: TextStyles.companyName,
// ),
],
),
SvgPicture.asset("assets/images/arrow.svg"),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const SizedBox(
height: 4,
),
const Text(
"Due Date",
style: TextStyles.textStyle62,
),
Text(
idueDate,
style: TextStyles.textStyle63,
),
// Text(
// companyName,
// style: TextStyles.companyName,
// ),
],
),
],
),
),
),
Card(
child: Container(
padding: const EdgeInsets.all(10),
decoration: const BoxDecoration(),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 4,
),
const Text(
"Invoice Amount",
style: TextStyles.textStyle62,
),
Text(
"₹ $invAmt",
style: TextStyles.textStyle65,
)
// Text("Asian Paints",style: TextStyles.textStyle34,),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const SizedBox(
height: 4,
),
isOverdue
? const Text(
"Payabe Amount",
style: TextStyles.textStyle62,
)
: const Text(
"Pay Now",
style: TextStyles.textStyle62,
),
Text(
"₹ $invAmt",
style: TextStyles.textStyle66,
),
],
),
],
),
SizedBox(
height: h1p * 1.5,
),
// Row(
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// isOverdue?
// const Text(
// "Interest",
// style: TextStyles.textStyle62,
// ):
// const Text(
// "You Save",
// style: TextStyles.textStyle62,
// ),
// Text(
// "₹ $savedAmount",
// style:isOverdue?
// TextStyles.textStyle73:
// TextStyles.textStyle77,
// ),
// ],
// ),
// ],
// ),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: GestureDetector(
onTap: () {
progress!.show();
getIt<TransactionManager>()
.changeSelectedInvoice(fullDetails);
progress.dismiss();
Navigator.pushNamed(context, savemoreDetails);
},
child: Image.asset(
"assets/images/viewetails.png")),
),
Row(
children: [
Expanded(
child: InkWell(
onTap: () async {
showDialog(
context: context,
builder: (context) => Padding(
padding:
const EdgeInsets.symmetric(
// vertical: h10p * 5,
),
child: AlertDialog(
shape:
const RoundedRectangleBorder(
borderRadius:
BorderRadius.all(
Radius.circular(
10.0))),
title: Row(
children: const [
Center(
child: Text("Comment"),
),
],
),
const SizedBox(
width: 10,
),
Expanded(
child: InkWell(
onTap: () async {
showDialog(
context: context,
builder: (context) => Padding(
padding:
const EdgeInsets.symmetric(
// vertical: h10p * 4,
),
child: StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
shape:
const RoundedRectangleBorder(
borderRadius:
BorderRadius.all(
Radius.circular(
10.0))),
title: const Center(
child: Text("Consent"),
),
content: Column(
mainAxisSize:
MainAxisSize.min,
children: [
Text(
"I agree and approve Xuriti and NBFC Ditya Finance Private Limited to disburse funds to yhe seller $companyName for invoice number -${fullDetails.invoiceNumber} on my behalf"),
TextField(
controller:
acceptController,
decoration:
const InputDecoration(
hintText:
"Leave a comment *"),
onChanged: (_) {
print(acceptController
.text);
acceptController
.text.isEmpty
? Row(
children: const [
Text(
"Please write a reason",
style: TextStyle(
color:
Colors.red),
),
],
)
: Container();
},
),
SizedBox(
height: h1p * 4,
),
InkWell(
onTap: () async {
userConsentGiven =
true;
String timeStamp =
DateTime.now()
.toString();
if (acceptController
.text
.isNotEmpty) {
progress!.show();
String? message = await getIt<
TransactionManager>()
.changeInvoiceStatus(
invoiceId,
"Confirmed",
index,
fullDetails,
timeStamp,
userConsentGiven,
acceptController
.text,
"This invoice has been confirmed and Xuriti and its financing partner is authorised to disburse funds to the seller as per the invoice generated on my behalf");
progress.dismiss();
ScaffoldMessenger
.of(context)
.showSnackBar(
SnackBar(
behavior:
SnackBarBehavior
.floating,
content:
Text(
message!,
style:
const TextStyle(color: Colors.green),
)));
} else {
Fluttertoast.showToast(
msg:
"Please write a reason",
textColor:
Colors.red);
}
Navigator.pop(
context,
);
},
child: Container(
height: h1p * 8,
width: w10p * 7.5,
decoration: BoxDecoration(
borderRadius:
BorderRadius
.circular(
6),
color: Colours
.pumpkin),
child: const Center(
child: Text(
"Accept",
style: TextStyles
.subHeading,
)),
),
),
],
),
);
}),
));
},
child: Container(
height: h1p * 9,
decoration: BoxDecoration(
color: Colours.successPrimary,
borderRadius: BorderRadius.circular(5)),
child: const Center(
child: Text(
"Accept",
style: TextStyles.textStyle46,
),
),
),
),
),
],
)
],
),
),
),
],
)),
),
);
}));
}
}
Please try to use this code as SnackBar and decorate you want,
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
behavior: SnackBarBehavior.floating,
content: Text(
message!,
style: const TextStyle(color: Colors.green),
),
backgroundColor: Colors.black,
action: SnackBarAction(
label: "Reload",
onPressed: () {
setState(() {});
})));
I Hope these things are solve your issue,
I bought an online template app and i am trying to hardcode my email and password credentials in my flutter frontend because i don't have access to the backend api yet to change from email/password auth to phone auth, so i want to force code the logic into my flutter widget.
This means i am trying to implement the onPressed: () { controller.login(); }, function on a login button to get me to the home screen with my customized widget.
The original code given to me works fine when i hardcode the credentials in the text form field but when i hardcode the text form field in my customized widget and use same onPressed: () { controller.login(); }, function it don't work.
I want to know if it's because of i'm in a different state management or there's something i'm failing to do.
I will give the original code and my customized UI code in the snippets for comparison.
PS: i even tried to use same text form field in my widget but hide it with Visibility() in flutter. When i use Visibility() in the original code, onPressed: () { controller.login(); }, works but when i use it in my customized widget, it doest.
How do work around this? If you need more clarification, i am willing to offer. Thanks.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../../../common/helper.dart';
import '../../../../../common/ui.dart';
import '../../../../models/setting_model.dart';
import '../../../../routes/app_routes.dart';
import '../../../../services/settings_service.dart';
import '../../../global_widgets/block_button_widget.dart';
import '../../../global_widgets/circular_loading_widget.dart';
import '../../../global_widgets/text_field_widget.dart';
import '../../controllers/auth_controller.dart';
class LoginView extends GetView<AuthController> {
final Setting _settings = Get.find<SettingsService>().setting.value;
#override
Widget build(BuildContext context) {
controller.loginFormKey = new GlobalKey<FormState>();
return Visibility(
visible: false,
child: WillPopScope(
onWillPop: Helper().onWillPop,
child: Scaffold(
appBar: AppBar(
title: Text(
"Login".tr,
style: Get.textTheme.headline6
.merge(TextStyle(color: context.theme.primaryColor)),
),
centerTitle: true,
backgroundColor: Get.theme.colorScheme.secondary,
automaticallyImplyLeading: false,
elevation: 0,
),
body: Form(
key: controller.loginFormKey,
child: ListView(
primary: true,
children: [
Stack(
alignment: AlignmentDirectional.bottomCenter,
children: [
Container(
height: 180,
width: Get.width,
decoration: BoxDecoration(
color: Get.theme.colorScheme.secondary,
borderRadius:
BorderRadius.vertical(bottom: Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Get.theme.focusColor.withOpacity(0.2),
blurRadius: 10,
offset: Offset(0, 5)),
],
),
margin: EdgeInsets.only(bottom: 50),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Text(
_settings.salonAppName,
style: Get.textTheme.headline6.merge(TextStyle(
color: Get.theme.primaryColor, fontSize: 24)),
),
SizedBox(height: 5),
Text(
"Welcome to the best salon service system!".tr,
style: Get.textTheme.caption.merge(
TextStyle(color: Get.theme.primaryColor)),
textAlign: TextAlign.center,
),
// Text("Fill the following credentials to login your account", style: Get.textTheme.caption.merge(TextStyle(color: Get.theme.primaryColor))),
],
),
),
),
Container(
decoration: Ui.getBoxDecoration(
radius: 14,
border:
Border.all(width: 5, color: Get.theme.primaryColor),
),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Image.asset(
'assets/icon/icon.png',
fit: BoxFit.cover,
width: 100,
height: 100,
),
),
),
],
),
Obx(() {
if (controller.loading.isTrue)
return CircularLoadingWidget(height: 300);
else {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Visibility(
visible: false,
maintainState: true,
child: TextFieldWidget(
labelText: "Email Address".tr,
hintText: "johndoe#gmail.com".tr,
initialValue: 'salon#demo.com',
onSaved: (input) =>
controller.currentUser.value.email = input,
validator: (input) => !input.contains('#')
? "Should be a valid email".tr
: null,
iconData: Icons.alternate_email,
),
),
Obx(() {
return Visibility(
visible: false,
maintainState: true,
child: TextFieldWidget(
labelText: "Password".tr,
hintText: "••••••••••••".tr,
initialValue: '123456',
onSaved: (input) =>
controller.currentUser.value.password = input,
validator: (input) => input.length < 3
? "Should be more than 3 characters".tr
: null,
),
);
}),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
Get.toNamed(Routes.FORGOT_PASSWORD);
},
child: Text("Forgot Password?".tr),
),
],
).paddingSymmetric(horizontal: 20),
BlockButtonWidget(
onPressed: () {
controller.login();
},
color: Get.theme.colorScheme.secondary,
text: Text(
"Login".tr,
style: Get.textTheme.headline6.merge(
TextStyle(color: Get.theme.primaryColor)),
),
).paddingSymmetric(vertical: 10, horizontal: 20),
TextButton(
onPressed: () {
//Get.toNamed(Routes.REGISTER);
},
child: Text("You don't have an account?".tr),
).paddingOnly(top: 20),
GestureDetector(
onTap: () {
Get.toNamed(Routes.SETTINGS_LANGUAGE);
},
child: Text(
Get.locale.toString().tr,
textAlign: TextAlign.center,
),
),
],
);
}
}),
],
),
),
),
),
);
}
}
THIS IS THE ORIGINAL WIDGET CODE
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../../routes/app_routes.dart';
import '../../../global_widgets/circular_loading_widget.dart';
import '../../../global_widgets/text_field_widget.dart';
import '../../controllers/auth_controller.dart';
import 'login_view.dart';
import 'pin_number.dart';
import 'keyboard_number.dart';
class PinScreen extends StatefulWidget {
const PinScreen({Key key}) : super(key: key);
#override
State<PinScreen> createState() => _PinScreenState();
}
class _PinScreenState extends State<PinScreen> {
List<String> currentPin = ["", "", "", ""];
TextEditingController pinOneController = TextEditingController();
TextEditingController pinTwoController = TextEditingController();
TextEditingController pinThreeController = TextEditingController();
TextEditingController pinFourController = TextEditingController();
var outlineInputBorder = OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.transparent),
);
int pinIndex = 0;
#override
Widget build(BuildContext context) {
final controller = Get.find<AuthController>();
controller.loginFormKey = new GlobalKey<FormState>();
return Form(
key: controller.loginFormKey,
child: SafeArea(
child: Column(
children: [
buildExitButton(),
Obx(() {
if (controller.loading.isTrue)
return CircularLoadingWidget(height: 300);
else {
return Expanded(
child: Container(
alignment: Alignment(0, 0.5),
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
buildSecurityText(),
SizedBox(height: 20.0),
buildPinRow(),
SizedBox(height: 10.0),
buildNumberPad(),
SizedBox(height: 20.0),
Visibility(
visible: false,
maintainState: true,
child: TextFieldWidget(
labelText: "Email Address".tr,
hintText: "johndoe#gmail.com".tr,
initialValue: 'salon#demo.com',
validator: (input) => !input.contains('#')
? "Should be a valid email".tr
: null,
iconData: Icons.alternate_email,
),
),
Obx(() {
return Visibility(
visible: false,
maintainState: true,
child: TextFieldWidget(
labelText: "Password".tr,
hintText: "••••••••••••".tr,
initialValue: '123456',
validator: (input) => input.length < 3
? "Should be more than 3 characters".tr
: null,
iconData: Icons.lock_outline,
keyboardType: TextInputType.visiblePassword,
suffixIcon: IconButton(
onPressed: () {
controller.hidePassword.value =
!controller.hidePassword.value;
},
color: Theme.of(context).focusColor,
icon: Icon(controller.hidePassword.value
? Icons.visibility_outlined
: Icons.visibility_off_outlined),
),
),
);
}),
Container(
child: new RichText(
text: new TextSpan(
children: [
new TextSpan(
recognizer: TapGestureRecognizer()
..onTap = () {
// Get.toNamed(Routes.REGISTER);
},
text: 'Forgot Pin ?',
style: new TextStyle(
color: Color(0xff3498DB),
fontSize: 14,
fontWeight: FontWeight.w500),
),
],
),
),
),
SizedBox(height: 20.0),
MaterialButton(
onPressed: () {
controller.login();
},
color: Color(0xff34495E),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.18),
),
padding: EdgeInsets.symmetric(
horizontal: 30, vertical: 10),
minWidth: double.infinity,
child: Text(
'Next',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600),
),
),
SizedBox(height: 32.0),
],
),
),
);
}
})
],
),
),
);
}
buildNumberPad() {
return Expanded(
child: Container(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
KeyboardNumber(
n: 1,
onPressed: () {
pinIndexSetup("1");
},
),
KeyboardNumber(
n: 2,
onPressed: () {
pinIndexSetup("2");
},
),
KeyboardNumber(
n: 3,
onPressed: () {
pinIndexSetup("3");
},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
KeyboardNumber(
n: 4,
onPressed: () {
pinIndexSetup("4");
},
),
KeyboardNumber(
n: 5,
onPressed: () {
pinIndexSetup("5");
},
),
KeyboardNumber(
n: 6,
onPressed: () {
pinIndexSetup("6");
},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
KeyboardNumber(
n: 7,
onPressed: () {
pinIndexSetup("7");
},
),
KeyboardNumber(
n: 8,
onPressed: () {
pinIndexSetup("8");
},
),
KeyboardNumber(
n: 9,
onPressed: () {
pinIndexSetup("9");
},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 60.0,
child: MaterialButton(
onPressed: null,
child: SizedBox(),
),
),
KeyboardNumber(
n: 0,
onPressed: () {
pinIndexSetup("0");
},
),
Container(
width: 60.0,
child: MaterialButton(
onPressed: () {
clearPin();
},
height: 60.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(60.0),
),
child: Image.asset(
'assets/icon/clear-symbol.png',
),
),
)
],
),
],
),
),
),
);
}
clearPin() {
if (pinIndex == 0)
pinIndex = 0;
else if (pinIndex == 4) {
setPin(pinIndex, "");
currentPin[pinIndex - 1] = "";
pinIndex--;
} else {
setPin(pinIndex, "");
currentPin[pinIndex - 1] = "";
pinIndex--;
}
}
pinIndexSetup(String text) {
if (pinIndex == 0)
pinIndex = 1;
else if (pinIndex < 4) pinIndex++;
setPin(pinIndex, text);
currentPin[pinIndex - 1] = text;
String strPin = "";
currentPin.forEach((e) {
strPin += e;
});
if (pinIndex == 4) print(strPin);
}
setPin(int n, String text) {
switch (n) {
case 1:
pinOneController.text = text;
break;
case 2:
pinTwoController.text = text;
break;
case 3:
pinThreeController.text = text;
break;
case 4:
pinFourController.text = text;
break;
}
}
buildExitButton() {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: MaterialButton(
onPressed: () {
Navigator.pop(context);
},
height: 50.0,
minWidth: 50.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0),
),
child: Icon(
Icons.clear,
color: Colors.black54,
),
),
),
],
);
}
buildSecurityText() {
return Column(
children: [
Align(
alignment: Alignment.topLeft,
child: Text(
'Enter PIN',
style: TextStyle(
color: Color(0xff151515),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
SizedBox(
height: 12,
),
Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.only(right: 80),
child: Text(
'Enter 4 digit PIN to access your account ',
style: TextStyle(
color: Color(0xff151515),
fontSize: 14,
fontWeight: FontWeight.w500,
fontStyle: FontStyle.normal,
),
),
),
),
],
);
}
buildPinRow() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
PINNumber(
outlineInputBorder: outlineInputBorder,
textEditingController: pinOneController,
),
PINNumber(
outlineInputBorder: outlineInputBorder,
textEditingController: pinTwoController,
),
PINNumber(
outlineInputBorder: outlineInputBorder,
textEditingController: pinThreeController,
),
PINNumber(
outlineInputBorder: outlineInputBorder,
textEditingController: pinFourController,
),
],
);
}
}
THIS IS MY CUSTOMIZED WIDGET TREE/CODE
this is two search and dropdown sections I have implemented using animated_custom_dropdown.
I want that "Get Quote Filter " button to place next to the(right side) set location drop down..................................................................................................................................
........................................................................................................................................
import 'package:animated_custom_dropdown/custom_dropdown.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../constants/colors.dart';
const _labelStyle = TextStyle(fontWeight: FontWeight.w600);
class FantomSearch extends StatefulWidget {
const FantomSearch({Key? key}) : super(key: key);
#override
State<FantomSearch> createState() => _FantomSearchState();
}
class _FantomSearchState extends State<FantomSearch> {
final formKey = GlobalKey<FormState>();
final List<String> list = ['Heating', 'Electricians', 'Repair or Service', 'Accessibility Planner'];
final jobRoleFormDropdownCtrl = TextEditingController(),
jobRoleSearchDropdownCtrl = TextEditingController();
#override
void dispose() {
jobRoleFormDropdownCtrl.dispose();
jobRoleSearchDropdownCtrl.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Scaffold(
//backgroundColor:AppGreen,
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle.dark.copyWith(
statusBarColor: AppGreen,
),
backgroundColor: AppGreen,
elevation: .10,
),
body: Container(
height: 200,
color: AppGreen,
child: ListView(
padding: const EdgeInsets.all(16.0),
children: [
CustomDropdown.search(
hintText: 'Search Services',
items: list,
controller: jobRoleSearchDropdownCtrl,
fillColor: DarkGreen,
),
const SizedBox(height: 24),
// using form for validation
Form(
key: formKey,
child: Padding(
padding: const EdgeInsets.only(right: 150),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CustomDropdown(
hintText: 'Set Location',
items: list,
controller: jobRoleFormDropdownCtrl,
excludeSelected: false,
fillColor: DarkGreen,
),
const SizedBox(height: 16),
SizedBox(
child: ElevatedButton(
onPressed: () {
if (!formKey.currentState!.validate()) {
return;
}
},
child: const Text(
'Get Quotes filter',
style: TextStyle(fontWeight: FontWeight.w600),
),
style: ElevatedButton.styleFrom(primary: ContainerGreen),
),
),
],
),
),
),
],
),
),
);
}
}
From your code, I believe that currently "Get quotes filter" showing below to the "Set Location" correct?
If this is the issue, you need to update Column widget to Row which is inside Padding.
Like,
Container(
height: 200,
child: SingleChildScrollView(
child: Column(
children: [
/**/
Row(
children: [
Expanded(
child: CustomDropdown.search(
hintText: 'Search Services',
items: list,
controller: jobRoleSearchDropdownCtrl,
fillColor: DarkGreen,
),
),
Padding(
padding: EdgeInsets.only(left: 15, top: 20, right: 15, bottom: 20),
child: Text(
"cancel"
),
)
],
),
const SizedBox(height: 24),
// using form for validation
Padding(
padding: const EdgeInsets.only(right: 70),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
/**/
Expanded(
child: CustomDropdown(
hintText: 'Set Location',
items: list,
controller: jobRoleFormDropdownCtrl,
excludeSelected: false,
fillColor: DarkGreen,
),
),
const SizedBox(width: 16),
SizedBox(
child: ElevatedButton(
onPressed: () {
if (!formKey.currentState!.validate()) {
return;
}
},
child: const Text(
'Get Quotes filter',
style: TextStyle(fontWeight: FontWeight.w600),
),
style: ElevatedButton.styleFrom(primary: Colors.green),
),
),
],
),
),
],
),
),
)
If this still not worked, please share the expected output and what you are getting now. Because I am not able to compile your code due to custom widgets.
I have updated the color so please update it as per your need. The output is something like,
I used InteractiveViewer here on my ProductDetail Page.
But when I pan and Zoom the image, the other widgets such as buttons and text are coming over it.
Here is my code:
class ProductDetail extends StatelessWidget {
final Product product;
ProductDetail({this.product});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
children: [
SizedBox(
height: 20
),
SizedBox(
height: 300,
width: MediaQuery.of(context).size.width -20,
child: InteractiveViewer(
child: Hero(
tag: product.id,
child: Carousel(
autoplay: false,
boxFit: BoxFit.cover,
dotBgColor: Colors.transparent,
dotColor: Colors.black.withOpacity(0.5),
images: [
AssetImage(product.imageUrl),
AssetImage(product.imageUrl),
AssetImage(product.imageUrl),
],
),
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width -20,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Text(
'₹ ${product.price}',
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
Text(
'₹ ${product.price}',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
decoration: TextDecoration.lineThrough,
color: Colors.grey
),
),
],
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(
child: ElevatedButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(getColorFromHex('#d1d1d1')),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.add_shopping_cart),
Text("Add to Cart", style: TextStyle(fontSize: 18)),
],
),
)
),
SizedBox(
child: ElevatedButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(getColorFromHex('#56a8e2')),
),
child: Row(
children: [
Icon(Icons.shopping_bag),
Text("Buy Now", style: TextStyle(fontSize: 18)),
],
),
)
),
],
),
),
],
),
),
);
}
}
How do I hide the other widgets like Text and buttons when I pan or zoom the image with the InteractiveViewer?
InteractiveViewer has two properties onInteractionStart and onInteractionEnd.
onInteractionStart → void Function(ScaleStartDetails details) : Called
when the user begins a pan or scale gesture on the widget.
onInteractionEnd → void Function(ScaleEndDetails details) : Called
when the user ends a pan or scale gesture on the widget.
You need to wrap the widgets that you wish to hide with the Visibility widget.
You can set - reset the visibility of the widgets wrapped under Visibility widget when user starts (onInteractionStart) and stops to pan or scale (onInteractionEnd).
Please see the code below, I had to make some changes to make it work :
import 'package:carousel_pro/carousel_pro.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
));
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: ProductDetail(),
),
);
}
}
class ProductDetail extends StatefulWidget {
ProductDetail({products});
#override
_ProductDetailState createState() => _ProductDetailState();
}
class _ProductDetailState extends State<ProductDetail> {
bool _visible = true;
TransformationController controller = TransformationController();
final Products products = Products(
id: 10,
imageUrl:
"https://cdn.pixabay.com/photo/2020/10/01/17/11/temple-5619197_960_720.jpg",
price: 20.00);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
children: [
SizedBox(height: 20),
SizedBox(
height: 300,
width: MediaQuery.of(context).size.width - 20,
child: InteractiveViewer(
transformationController: controller,
onInteractionStart: (scale) {
setState(() => _visible = false);
},
onInteractionEnd: (scale) {
setState(() {
controller.value = Matrix4.identity();
_visible = true;
});
},
child: Hero(
tag: products.id,
child: Carousel(
autoplay: false,
boxFit: BoxFit.cover,
dotBgColor: Colors.transparent,
dotColor: Colors.black.withOpacity(0.5),
images: [
NetworkImage(products.imageUrl),
NetworkImage(products.imageUrl),
NetworkImage(products.imageUrl),
],
),
),
),
),
Visibility(
visible: _visible,
child: SizedBox(
width: MediaQuery.of(context).size.width - 20,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Text(
'₹ ${products.price.toString()}',
style: TextStyle(
fontSize: 25, fontWeight: FontWeight.bold),
),
Text(
'₹ ${products.price.toString()}',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
decoration: TextDecoration.lineThrough,
color: Colors.grey),
),
],
),
),
),
),
Visibility(
visible: _visible,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(
child: ElevatedButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.cyanAccent),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.add_shopping_cart),
Text("Add to Cart", style: TextStyle(fontSize: 18)),
],
),
)),
SizedBox(
child: ElevatedButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.limeAccent),
),
child: Row(
children: [
Icon(Icons.shopping_bag),
Text("Buy Now", style: TextStyle(fontSize: 18)),
],
),
)),
],
),
),
),
],
),
),
);
}
}
class Products {
final int id;
final String imageUrl;
final double price;
Products({
this.id,
this.imageUrl,
this.price,
});
Products copyWith({
int id,
String imageUrl,
double price,
}) {
return Products(
id: id ?? this.id,
imageUrl: imageUrl ?? this.imageUrl,
price: price ?? this.price,
);
}
}
i have created a page where a user who will click a title to edit the contents and can add and delete devices that the article is attached to,
but i could not figure it out on how to program the drop down dynamically, to add more drop downs when a user press the add device button,
the additional function they want me to add as well is on the Dropdown list, when they select 'NONE' it should remove that dropdown as well,
i am planning to use mysql,xampp or sqlite for my database if im done with the UI,
import 'package:flutter/material.dart';
import 'package:surveyadminpanel/Contents/tabbar.dart';
import 'package:surveyadminpanel/widgets/button.dart';
import 'package:surveyadminpanel/widgets/simplewidgets.dart';
import 'homepage.dart';
import 'dart:ui';
class Item {
Item(this.name);
String name;
}
class editsurvey extends StatefulWidget {
#override
_editsurveyState createState() => _editsurveyState();
}
class _editsurveyState extends State<editsurvey>{
int surveyquestionnum = 1;
int surveyquestiontotal = 1;
List<Item> selectedUser = [null, null];
List<Item> selecteddata = [null, null];
List<Item> users;
int linkdevices = 1;
String dropdownvalue= "SELECT FROM DROPDOWN";
List data = [
'Sample Data 1',
'Sample Data 2',
'Sample Data 3',
'Sample Data 4',
'Sample Data 5',
'Sample Data 6',
];
#override
void initState() {
super.initState();
users = <Item>[
Item('Sample device 1'),
Item('Sample device 2'),
Item('Sample device 3'),
Item('Sample device 4'),
];
}
#override
Widget _dropdownbutton (List<Item> userlist, int index){
return Container(
padding: EdgeInsets.all(1),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.all(
Radius.circular(15.0) //
),
),
child: DropdownButton<Item>(
underline: SizedBox(),
isExpanded: true,
icon: Icon(Icons.arrow_drop_down),
hint: Text(" $dropdownvalue"),
value: selectedUser[index],
onChanged: (Item Value) {
setState(() {
selectedUser[index] = Value;
});
},
items: userlist.map((Item user) {
return DropdownMenuItem<Item>(
value: user,
child: Row(
children: <Widget>[
SizedBox(width: 10,),
Text(
user.name,
style: TextStyle(color: Colors.black),
),
],
),
);
}).toList(),
),
);
}
Widget _text(texthere,bold,size,color){
return Text(texthere,style: TextStyle(fontWeight: bold,fontSize: size,color: color),overflow: TextOverflow.ellipsis,maxLines: 1);
}
Widget _logo(){
return InkWell(
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => admincontent()),
);
},
child: Container(width: 500,height: 200,child: Image.asset("images/v2.jpg")));
}
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
double screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
title: Padding(padding: EdgeInsets.only(left: 30),
child: RichText(
text: TextSpan(
text: 'Good Morning Welcome to Sample:',
style: TextStyle(
color: Colors.blueAccent, fontSize: 18),
children: <TextSpan>[
TextSpan(text: usernametitle,
style: TextStyle(
color: Colors.black, fontSize: 18),
)
]
),
)
),
elevation: 1,
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
leading: _logo(),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.notifications),
color: Colors.blueAccent,
tooltip: 'Show Notification',
onPressed: () {
},
),
IconButton(
color: Colors.lightGreen,
icon: const Icon(Icons.account_circle),
tooltip: 'Check your Profile',
onPressed: () {
},
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
_text("EDIT SURVEY", FontWeight.bold, 20,Colors.blue),
roundedRectButton("BACK", signInGradients),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: screenWidth/1.6,
height: screenHeight/1.6,
decoration: BoxDecoration(
color: Colors.orange[200],
borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_text("SURVEY TITLE", FontWeight.bold, 17,Colors.white),
_text(data[0], FontWeight.bold, 19, Colors.black),
_text("DATE CREATED", FontWeight.bold, 17,Colors.white),
_text(data[1], null, 19, Colors.black),
_text("CURRENT STATUS", FontWeight.bold, 17,Colors.white),
_text(data[2], null, 19, Colors.black),
_text("LANGUAGE VERSION", FontWeight.bold, 17,Colors.white),
_text(data[3], null, 19, Colors.black),
_text("NUMBERS OF ASSESSORS", FontWeight.bold, 17,Colors.white),
_text(data[4], null, 19, Colors.black),
_text("TOTAL RENDERED SURVEYS", FontWeight.bold, 17,Colors.white),
_text(data[5], null, 19, Colors.black),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
InkWell(
onTap: (){
},
child: Container(width: 100,height: 50,child: Text("EDIT SURVEY")),
),
_text("LINKED DEVICES : $linkdevices", FontWeight.bold, 17,Colors.white),
],
)
],
),
)
),
Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1.0,
style: BorderStyle.solid
)
),
width: screenWidth/1.6,
height: screenHeight/1.6,
child: Column(
children: <Widget>[
_text("DEVICES PINNED", FontWeight.bold, 20,Colors.blue),
ListView.separated(
shrinkWrap: true,
itemCount: linkdevices,
itemBuilder: (context, index){
return Padding(
padding: const EdgeInsets.all(8.0),
child: _dropdownbutton(users, index),
);
},
separatorBuilder: (context, index) => Container(height: 10),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
InkWell(
child: roundedRectButton("ADD DEVICE", signInGradients),
onTap: (){
},
),
InkWell(
child: roundedRectButton("CLEAR ALL DEVICE", signInGradients),
onTap: (){
},
),
],
),
],
),
),
],
)
],
),
),
),
);
}
}
The Plan
The Result
im still trying to figure this out, but if someone can give me a lift,, im gonna be very thankful to who can help me out here ,,
You can copy paste run full code below
You can increase linkdevices and selectedUser
code snippet
List<Item> selectedUser = [null];
...
InkWell(
child: Text("ADD DEVICE"),
onTap: () {
selectedUser.add(null);
linkdevices ++;
setState(() {
});
working demo
full code
import 'package:flutter/material.dart';
class Item {
Item(this.name);
String name;
}
class editsurvey extends StatefulWidget {
#override
_editsurveyState createState() => _editsurveyState();
}
class _editsurveyState extends State<editsurvey> {
int surveyquestionnum = 1;
int surveyquestiontotal = 1;
List<Item> selectedUser = [null];
List<Item> selecteddata = [null, null];
List<Item> users;
int linkdevices = 1;
String dropdownvalue = "SELECT FROM DROPDOWN";
List data = [
'Sample Data 1',
'Sample Data 2',
'Sample Data 3',
'Sample Data 4',
'Sample Data 5',
'Sample Data 6',
];
#override
void initState() {
super.initState();
users = <Item>[
Item('Sample device 1'),
Item('Sample device 2'),
Item('Sample device 3'),
Item('Sample device 4'),
];
}
#override
Widget _dropdownbutton(List<Item> userlist, int index) {
return Container(
padding: EdgeInsets.all(1),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.all(Radius.circular(15.0) //
),
),
child: DropdownButton<Item>(
underline: SizedBox(),
isExpanded: true,
icon: Icon(Icons.arrow_drop_down),
hint: Text(" $dropdownvalue"),
value: selectedUser[index],
onChanged: (Item Value) {
print(Value.toString());
print(index);
setState(() {
selectedUser[index] = Value;
});
},
items: userlist.map((Item user) {
return DropdownMenuItem<Item>(
value: user,
child: Row(
children: <Widget>[
SizedBox(
width: 10,
),
Text(
user.name,
style: TextStyle(color: Colors.black),
),
],
),
);
}).toList(),
),
);
}
Widget _text(texthere, bold, size, color) {
return Text(texthere,
style: TextStyle(fontWeight: bold, fontSize: size, color: color),
overflow: TextOverflow.ellipsis,
maxLines: 1);
}
Widget _logo() {
return InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => admincontent()),
);
},
child: Container(
width: 500, height: 200, child: Image.asset("images/v2.jpg")));
}
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
double screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
title: Padding(
padding: EdgeInsets.only(left: 30),
child: RichText(
text: TextSpan(
text: 'Good Morning Welcome to Sample:',
style: TextStyle(color: Colors.blueAccent, fontSize: 18),
children: <TextSpan>[
TextSpan(
text: "usernametitle",
style: TextStyle(color: Colors.black, fontSize: 18),
)
]),
)),
elevation: 1,
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
leading: _logo(),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.notifications),
color: Colors.blueAccent,
tooltip: 'Show Notification',
onPressed: () {},
),
IconButton(
color: Colors.lightGreen,
icon: const Icon(Icons.account_circle),
tooltip: 'Check your Profile',
onPressed: () {},
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
_text("EDIT SURVEY", FontWeight.bold, 20.0, Colors.blue),
//roundedRectButton("BACK", signInGradients),
Text("BACK"),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: screenWidth / 1.6,
height: screenHeight / 1.6,
decoration: BoxDecoration(
color: Colors.orange[200],
borderRadius:
new BorderRadius.all(new Radius.circular(20.0)),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_text("SURVEY TITLE", FontWeight.bold, 17.0,
Colors.white),
_text(data[0], FontWeight.bold, 19.0, Colors.black),
_text("DATE CREATED", FontWeight.bold, 17.0,
Colors.white),
_text(data[1], null, 19.0, Colors.black),
_text("CURRENT STATUS", FontWeight.bold, 17.0,
Colors.white),
_text(data[2], null, 19.0, Colors.black),
_text("LANGUAGE VERSION", FontWeight.bold, 17.0,
Colors.white),
_text(data[3], null, 19.0, Colors.black),
_text("NUMBERS OF ASSESSORS", FontWeight.bold, 17.0,
Colors.white),
_text(data[4], null, 19.0, Colors.black),
_text("TOTAL RENDERED SURVEYS", FontWeight.bold,
17.0, Colors.white),
_text(data[5], null, 19.0, Colors.black),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
InkWell(
onTap: () {},
child: Container(
width: 100,
height: 50,
child: Text("EDIT SURVEY")),
),
_text("LINKED DEVICES : $linkdevices",
FontWeight.bold, 17.0, Colors.white),
],
)
],
),
)),
Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1.0,
style: BorderStyle.solid)),
width: screenWidth / 1.6,
height: screenHeight / 1.6,
child: Column(
children: <Widget>[
_text("DEVICES PINNED", FontWeight.bold, 20.0,
Colors.blue),
ListView.separated(
shrinkWrap: true,
itemCount: linkdevices,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: _dropdownbutton(users, index),
);
},
separatorBuilder: (context, index) => Container(height: 10),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
InkWell(
child: Text("ADD DEVICE"),
onTap: () {
selectedUser.add(null);
linkdevices ++;
setState(() {
});
/*listWidget.add( ListView.separated(
shrinkWrap: true,
itemCount: linkdevices,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: _dropdownbutton(users, index),
);
},
separatorBuilder: (context, index) => Container(height: 10),
));
setState(() {
});*/
},
),
InkWell(
child: Text("CLEAR ALL DEVICE"),
onTap: () {},
),
],
),
],
),
),
],
)
],
),
),
),
);
}
}
class admincontent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container();
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: editsurvey(),
);
}
}