Flutter Image Picker to Image URL - flutter

i have the following code below. ive used image_picker package to upload pictures to be used as profile pictures. ive commented my previous code that uses an image url instead. my question is if there's a way to convert the images uploaded to images url, that way, i can display the profile picture when i get into the home screen.
// ignore_for_file: use_build_context_synchronously, deprecated_member_use
import 'dart:io';
import 'package:cloud_functions/cloud_functions.dart';
import 'package:firebase_auth/firebase_auth.dart' as firebase;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:ibchat/pages/verify_email_page.dart';
import 'package:ibchat/screens/screens.dart';
import 'package:ibchat/theme.dart';
import 'package:image_picker/image_picker.dart';
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
import '../app.dart';
class SignUpScreen extends StatefulWidget {
static Route get route => MaterialPageRoute(
builder: (context) => const SignUpScreen(),
);
const SignUpScreen({Key? key}) : super(key: key);
#override
State<SignUpScreen> createState() => _SignUpScreenState();
}
class _SignUpScreenState extends State<SignUpScreen> {
final auth = firebase.FirebaseAuth.instance;
final functions = FirebaseFunctions.instance;
final _formKey = GlobalKey<FormState>();
PickedFile? _imageFile;
final ImagePicker _picker = ImagePicker();
//final _profilePictureController = TextEditingController();
final _nameController = TextEditingController();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _designationController = TextEditingController();
final _companyController = TextEditingController();
final _emailRegex = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+");
bool _loading = false;
Future<void> _signUp() async {
if (_formKey.currentState!.validate()) {
setState(() {
_loading = true;
});
try {
// Authenticate with Firebase
final creds =
await firebase.FirebaseAuth.instance.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
final user = creds.user;
if (user == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Member not found')),
);
return;
}
// Set Firebase display name and profile picture
List<Future<void>> futures = [
/*if (_profilePictureController.text.isNotEmpty)
creds.user!.updatePhotoURL(_profilePictureController.text),*/
/*if (_picker.toString().isNotEmpty)
creds.user!.updatePhotoURL(_picker.toString()),*/
creds.user!.updateDisplayName(_nameController.text),
];
await Future.wait(futures);
// Create Stream user and get token using Firebase Functions
final callable = functions.httpsCallable('createStreamUserAndGetToken');
final results = await callable();
// Connect user to Stream and set user data
final client = StreamChatCore.of(context).client;
await client.connectUser(
User(
//image: _profilePictureController.text,
//image: _picker.toString(),
id: creds.user!.uid,
name: _nameController.text,
extraData: {
"email": _emailController.text,
"designation": _designationController.text,
"company": _companyController.text,
}),
results.data,
);
// Navigate to verify email page
await Navigator.of(context).pushReplacement(VerifyEmailPage.route);
} on firebase.FirebaseAuthException catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.red,
content: Text(e.message ?? 'Verification error')),
);
} catch (e, st) {
logger.e('Sign up error', e, st);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.red, content: Text('An error occured')),
);
}
setState(() {
_loading = false;
});
}
}
String? _nameInputValidator(String? value) {
if (value == null || value.isEmpty) {
return 'Name cannot be empty';
}
return null;
}
String? _emailInputValidator(String? value) {
if (value == null || value.isEmpty) {
return 'Email cannot be empty';
}
if (!_emailRegex.hasMatch(value)) {
return 'Not a valid email';
}
return null;
}
String? _passwordInputValidator(String? value) {
if (value == null || value.isEmpty) {
return 'Password Cannot be empty';
}
if (value.length <= 6) {
return 'Password needs to be longer than 6 characters';
}
return null;
}
#override
void dispose() {
//_profilePictureController.dispose();
_nameController.dispose();
_emailController.dispose();
_passwordController.dispose();
_designationController.dispose();
_companyController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Image.asset('assets/images/logo.png', scale: 2),
backgroundColor: Colors.transparent,
),
body: (_loading)
? const Center(
child: SizedBox(
height: 100,
width: 100,
child: CircularProgressIndicator(color: AppColors.accent)))
: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
onWillPop: () async => false,
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 24),
child: Text(
'Registeration',
style: GoogleFonts.lato(
fontSize: 28, fontWeight: FontWeight.w800),
),
),
/*Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _profilePictureController,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Picture URL',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.url,
),
),*/
imageProfile(),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _nameController,
validator: _nameInputValidator,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Name',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.name,
autofillHints: const [
AutofillHints.name,
AutofillHints.username
],
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _emailController,
validator: _emailInputValidator,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Email',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.emailAddress,
autofillHints: const [AutofillHints.email],
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _passwordController,
validator: _passwordInputValidator,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Password',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
obscureText: true,
enableSuggestions: false,
autocorrect: false,
keyboardType: TextInputType.visiblePassword,
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _designationController,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Designation',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.name,
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _companyController,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Company',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.name,
),
),
const SizedBox(height: 30),
Padding(
padding: const EdgeInsets.all(12.0),
child: SizedBox(
height: 50,
width: 250,
child: ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
))),
onPressed: _signUp,
child: Text('Sign Up',
style: GoogleFonts.lato(
fontSize: 21,
fontWeight: FontWeight.bold,
color: Colors.black)),
),
),
),
const SizedBox(
height: 20,
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Divider(),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Already a Member?',
style: Theme.of(context).textTheme.subtitle2),
const SizedBox(width: 8),
TextButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
primary: AppColors.accent),
onPressed: () {
Navigator.of(context).push(SignInScreen.route);
},
child: const Text('Sign In',
style: TextStyle(color: AppColors.secondary)),
),
],
),
],
),
),
),
),
);
}
Widget imageProfile() {
return Center(
child: Stack(
children: <Widget>[
CircleAvatar(
radius: 34,
backgroundImage: _imageFile == null
? const AssetImage("assets/images/profile_default.png")
as ImageProvider
: FileImage(File(_imageFile!.path)),
),
Positioned(
bottom: -2,
right: -1,
child: InkWell(
onTap: () {
showModalBottomSheet(
context: context,
builder: ((builder) => bottomSheet()),
);
},
child: const Icon(CupertinoIcons.camera_fill,
color: AppColors.accent, size: 20)),
)
],
),
);
}
Widget bottomSheet() {
return Container(
height: 100,
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 20,
),
child: Column(
children: <Widget>[
const Text(
"Upload a Profile Photo",
style: TextStyle(
fontSize: 18.0,
),
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton.icon(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
icon: const Icon(CupertinoIcons.camera_fill),
onPressed: () {
takePhoto(ImageSource.camera);
},
label: const Text("Camera")),
FlatButton.icon(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
icon:
const Icon(CupertinoIcons.photo_fill_on_rectangle_fill),
onPressed: () {
takePhoto(ImageSource.gallery);
},
label: const Text("Photos")),
],
)
],
));
}
void takePhoto(ImageSource source) async {
final pickedFile = await _picker.getImage(source: source);
setState(() {
_imageFile = pickedFile!;
});
}
}

Related

Field has not been initialized

tags in my code is a List which is comes from previous page,
I want to be able to remove and add items to it in my current page,
first I tried to initialize it in my initState but when I want to remove tags it doesn't work.
I guessed it is about the initialization, so I removed it from initState but now I am getting this error message Field 'tags' has not been initialized. I will attach my full code and I appreciate any suggestions about it. Thanks.
PS: I tried initializing tags with tags=[] in my initState but I can't remove any of the tags. It has a GestureDetector to remove tags, when I press it nothing happens. I guess initializing in the build function causes it, but I don't know where to initialize it that I could be able to edit it while the list is coming from another screen.
also when I added tags = widget.tags.where((e) => e != null && e != "").toList(); to my initiState and I inspect tags value, there is an empty string in addtion to other values at the end of the list.
import 'dart:convert';
import 'dart:developer';
import 'package:double_back_to_close/toast.dart';
import 'package:flutter/material.dart';
import 'package:pet_store/main.dart';
import 'package:pet_store/widgets/tag_preview.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'dart:async';
import 'dart:math';
import 'package:http/http.dart' as http;
import 'package:pet_store/widgets/tag_retrieve_preview.dart';
import 'utils/utils.dart';
class update_pet extends StatefulWidget {
var id;
var name;
var status;
var category;
var tags ;
update_pet(
{this.id, this.name, this.status, this.category, this.tags, Key? key})
: super(key: key);
#override
_update_petState createState() => _update_petState();
}
class _update_petState extends State<update_pet> {
final _picker = ImagePicker();
Future<void> _openImagePicker() async {
final XFile? pickedImage =
await _picker.pickImage(source: ImageSource.gallery);
if (pickedImage != null) {
setState(() {
final bytes = File(pickedImage.path).readAsBytesSync();
base64Image = "data:image/png;base64," + base64Encode(bytes);
});
}
}
String? base64Image;
TextEditingController nameController = TextEditingController();
TextEditingController categoryController = TextEditingController();
TextEditingController tagController = TextEditingController();
late File imageFile;
late List<dynamic> tags;
bool isLoading = false;
void initState() {
super.initState();
nameController.text = widget.name;
categoryController.text = widget.category;
addTag();
}
void addTag() {
setState(() {
tags.add(tagController.text);
tagController.clear();
});
}
String? dropdownvalue;
var items = [
'available',
'pending',
'sold',
];
#override
Widget build(BuildContext context) {
tags = widget.tags.where((e) => e != null && e != "").toList();
// inspect(tags);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.indigo,
title: const Text('Update a pet'),
leading: GestureDetector(
child: Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
onTap: () {
// Navigator.pop(context);
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
PetStoreHomePage(LoggedIn: true),
),
(route) => false,
);
},
),
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Card(
child: Container(
padding: const EdgeInsets.all(10),
child: Column(
children: [
const ListTile(
// leading,
title: Text(
"General Information",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
TextField(
controller: nameController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: "Enter your pet's name",
),
),
DropdownButton(
hint: const Text('Select Status'),
value: dropdownvalue,
icon: const Icon(Icons.keyboard_arrow_down),
items: items.map((String items) {
return DropdownMenuItem(
value: items,
child: Text(items),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
dropdownvalue = newValue!;
});
},
),
],
),
),
elevation: 8,
shadowColor: Colors.grey.shade300,
margin: const EdgeInsets.all(20),
shape: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.white)),
),
Card(
child: Container(
padding: const EdgeInsets.all(10),
child: Column(
children: [
const ListTile(
// leading,
title: Text(
"Category",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
TextField(
controller: categoryController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: "Specify your pet's category",
),
),
],
),
),
elevation: 8,
shadowColor: Colors.grey.shade300,
margin:
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
shape: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.white)),
),
Card(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const ListTile(
// leading,
title: Text(
"Tags",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Flexible(
fit: FlexFit.loose,
child: ListView.builder(
shrinkWrap: true,
itemCount: tags.length,
itemBuilder: (_, index) {
print(tags);
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 5.0, vertical: 3.0),
child: GestureDetector(
child: tagRetrievePreview(tags[index]),
onTap: () {
print("REMOVED "+tags[index]);
tags.removeAt(index);
}),
);
},
),
),
TextField(
controller: tagController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Specify your pet's tags",
suffixIcon: IconButton(
icon: const Icon(
Icons.add_circle_outline_sharp,
color: Color.fromARGB(255, 129, 128, 128),
size: 30,
),
onPressed: () {
addTag();
print(tags);
},
),
),
),
],
),
),
elevation: 8,
shadowColor: Colors.grey.shade300,
margin:
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
shape: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.white)),
),
Card(
child: Column(
children: [
const ListTile(
title: Text(
"Images",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
(base64Image != null)
? SizedBox(
width: 100,
height: 100,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
image: DecorationImage(
image: image(base64Image!).image,
fit: BoxFit.fill),
)),
)
: SizedBox(
width: 100,
height: 100,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.grey.shade300,
),
child: Icon(
Icons.camera_alt,
color: Colors.grey.shade800,
size: 30,
),
),
),
Container(
margin: const EdgeInsets.symmetric(horizontal: 100),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
const Color.fromARGB(255, 129, 128, 128)),
padding: MaterialStateProperty.all(
const EdgeInsets.symmetric(horizontal: 20)),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
side: const BorderSide(
color: Color.fromARGB(255, 129, 128, 128),
width: 2.0,
),
),
),
),
child: const Text(
'Select Image',
style:
TextStyle(fontSize: 15.0, color: Colors.white),
),
onPressed: _openImagePicker),
),
],
),
elevation: 8,
shadowColor: Colors.grey.shade300,
margin:
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
shape: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.white)),
),
Container(
margin: const EdgeInsets.symmetric(horizontal: 120),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.indigo),
padding: MaterialStateProperty.all(
const EdgeInsets.symmetric(horizontal: 40)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
side: const BorderSide(
color: Colors.indigo,
width: 2.0,
),
),
),
),
child: isLoading
? const SizedBox(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
Colors.white)),
height: 15.0,
width: 15.0,
)
: const Text(
'Update Pet',
style:
TextStyle(fontSize: 17.0, color: Colors.white),
),
onPressed: () async {
if (nameController.text.isEmpty) {
nameController.text = widget.name;
}
if (tagController.text.isEmpty) {
tagController.text = widget.tags;
}
if (categoryController.text.isEmpty) {
categoryController.text = widget.category;
}
if (dropdownvalue == null) {
dropdownvalue = widget.status;
}
print('Pressed');
Map data = {
"id": random.nextInt(10000),
///random it integer
"name": nameController.text,
"category": {
"id": set_category_id(categoryController.text),
"name": categoryController.text,
},
"photoUrls": [base64Image],
"tags": set_tags(tags),
"status": dropdownvalue
};
var body = json.encode(data);
var response = await http.put(
Uri.parse(
"https://api.training.testifi.io/api/v3/pet"),
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: body);
print(response.body);
print(response.statusCode);
if (response.statusCode == 201 ||
response.statusCode == 200) {
print('success');
Toast.show("Pet is successfully updated.", context);
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
PetStoreHomePage(LoggedIn: true),
),
(route) => false,
);
} else {
Toast.show(
"ERROR! Updating pet failed. Please try again.",
context);
}
}),
),
],
),
),
),
);
}
}
tags = widget.tags.where((e) => e != null && e != "").toList();
This line in build method will constantly take value from widget.tags and create a list of items thats not null and empty.
Please add this in initState.
Just initialize it
List<dynamic> tags = [];
PS: I tried initializing tags with tags=[] in my initState but I can't
remove any of the tags.
You need to add setState to rebuild the page.

setState not updating the value in the screen using Flutter desktop

So I'm trying to update the value of the drop down list using the setState, but when I select a value from the list, the value on the screen won't be able to change
import 'package:demo_app_admin/Custom/custom_Font.dart';
import 'package:flutter/material.dart';
import '/Custom/Custom_Raised_Bottun.dart';
import '/Custom/Header.dart';
import '/Custom/inputField.dart';
class LoginView extends StatefulWidget {
#override
_LoginViewState createState() => _LoginViewState();
}
class _LoginViewState extends State<LoginView> {
#override
Widget build(BuildContext context) {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final isKeyboard = MediaQuery.of(context).viewInsets.bottom != 0;
String _dropdownvalue = "Global admin";
List<String> _items = <String> ["Global admin", "Institution admin"];
return Scaffold(
body: Container(
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(begin: Alignment.topCenter, colors: [
Colors.teal[700]!,
Colors.teal[200]!,
Colors.teal[400]!
]),
),
child: Column(
children: <Widget>[
const SizedBox(
height: 80,
),
if (!isKeyboard)
Header(
padding: const EdgeInsets.all(20),
crossAxisAlignment: CrossAxisAlignment.start,
head: "Welcome",
headTextStyle:
const TextStyle(color: Colors.white, fontSize: 40),
sizedBoxHeight: 10,
subtitle: "Sign In to Your Admin Account",
subtitleTextStyle:
const TextStyle(color: Colors.white, fontSize: 18),
),
Expanded(
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(60),
topRight: Radius.circular(60),
)),
child: Padding(
padding: const EdgeInsets.all(30),
child: SingleChildScrollView(
reverse: true,
padding: EdgeInsets.all(32),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
const SizedBox(
height: 40,
),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10)),
child: Column(
children: <Widget>[
InputField(
labelText: 'Email',
padding: EdgeInsets.all(10),
borderSide: BorderSide(color: Colors.grey),
hintText: "Enter your email",
color: Colors.grey,
inputBorder: InputBorder.none,
obscureText: false,
enableSuggestion: true,
autoCorrect: true,
onSaved: (value) {},
// (value){controller.email = value!;},
validator: (value) {
if (value == null) {
print("ERROR");
}
},
),
InputField(
labelText: 'Password',
padding: EdgeInsets.all(10),
borderSide: BorderSide(color: Colors.grey),
hintText: "Enter your password",
color: Colors.grey,
inputBorder: InputBorder.none,
obscureText: true,
enableSuggestion: false,
autoCorrect: false,
onSaved: (value) {},
// (value){ controller.password = value!;},
validator: (value) {
if (value == null) {
print("ERROR");
}
},
),
],
),
),
const SizedBox(
height: 40,
),
here is the issue
DropdownButton<String>(
value: _dropdownvalue,
icon: Icon(Icons.keyboard_arrow_down),
items: _items.map((String _items) {
return DropdownMenuItem<String>(
value: _items,
child: CustomFont(text: _items),
);
}).toList(),
onChanged: (value) {
setState(() => _dropdownvalue = value!);
}),
const SizedBox(
height: 40,
),
CustomRaisedButton(
width: 200,
height: 50.0,
margin: const EdgeInsets.symmetric(horizontal: 50),
color: Colors.teal.shade500,
borderRadius: BorderRadius.circular(10),
text: "LOGIN",
textColor: Colors.white,
fontSize: 17,
fontWeight: FontWeight.bold,
function: () {}
// {
// _formKey.currentState?.save();
// if(_formKey.currentState?.validate() !=null){
// controller.signInWithEmailAndPassword();
// }
// },
),
SizedBox(
height: 10,
),
],
),
),
),
),
))
],
),
),
);
}
}
The issue is here, you are declaring variables inside build. Therefore, variables get reset to default value on every build. Means setState.
Declare variables outside the build method.
class _LoginViewState extends State<LoginView> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _dropdownvalue = "Global admin";
List<String> _items = <String>["Global admin", "Institution admin"];
#override
Widget build(BuildContext context) {
final isKeyboard = MediaQuery.of(context).viewInsets.bottom != 0;
return Scaffold(
More about StatefulWidget.

Can i Select Multiple Accounts in a Banking app and pay them different amounts at the same time in flutter?

import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:keyboard_dismisser/keyboard_dismisser.dart';
import 'package:money_formatter/money_formatter.dart';
import 'package:shukela_app/api/banking_app_api.dart';
import 'package:shukela_app/screens/stokvel_detail.dart';
import 'package:shukela_app/screens/stokvels.dart';
import 'package:shukela_app/utils/constants.dart';
import 'package:shukela_app/utils/global_variables.dart';
import 'package:sizer/sizer.dart';
import 'package:shukela_app/model/bankingapp_model.dart';
import '../utils/user_preferences.dart';
class PayMultipleStokvelScreen extends StatefulWidget {
const PayMultipleStokvelScreen({Key? key}) : super(key: key);
#override
State<PayMultipleStokvelScreen> createState() =>
_PayMultipleStokvelScreenState();
}
TextEditingController txtSearch = TextEditingController();
TextEditingController txtAmount = TextEditingController();
class _PayMultipleStokvelScreenState extends State<PayMultipleStokvelScreen> {
String? selectedType;
bool hasText = false;
String buttonText = "PAY NOW";
bool isLoading = false;
Widget? showHideIcon() {
if (hasText) {
return IconButton(
icon: const Icon(
Icons.clear,
color: AppColors.primaryBlue,
),
onPressed: () {
txtSearch.clear();
setState(() {
hasText = false;
});
},
);
} else {
return null;
}
}
// void _showMultiSelectDialog(BuildContext context) async {
// await showDialog(
// context: context,
// builder: (ctx) {
// return MultiSelectDialog(
// items: _animals.map((e) => MultiSelectItem(e, e)).toList(),
// initialValue: _selectedAnimals,
// onConfirm: (values) {...},
// );
// },
// );
// }
double? balance;
final _formKey = GlobalKey<FormState>();
var selectedValue;
List<StokvelDetail> selectedStokvel = [];
#override
void initState() {
super.initState();
balance = double.parse(UserPreferences.getBalance() ?? '');
}
mf() {
MoneyFormatter mf = MoneyFormatter(amount: balance!);
return mf;
}
StokvelListState currentState = StokvelListState.showAllListState;
#override
Widget build(BuildContext context) => KeyboardDismisser(
gestures: const [GestureType.onTap],
child: SafeArea(
child: Scaffold(
backgroundColor: AppColors.secondaryColor,
appBar: AppBar(
backgroundColor: AppColors.secondaryColor,
elevation: 0,
title: const Text('Pay Multiple Stokvel',
style: screenTitleTextStyle),
leading: IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: AppColors.primaryBlue,
),
onPressed: () => Navigator.pop(context),
),
),
body: Form(
key: _formKey,
child: Column(
children: [
SizedBox(height: 5.h),
Container(
height: 6.h,
width: 98.w,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: TypeAheadFormField<Stokvel?>(
debounceDuration: const Duration(milliseconds: 500),
hideSuggestionsOnKeyboardHide: false,
suggestionsBoxDecoration: const SuggestionsBoxDecoration(
constraints: BoxConstraints(maxHeight: 450),
color: AppColors.secondaryColor,
borderRadius: BorderRadius.all(Radius.circular(10))),
textFieldConfiguration: TextFieldConfiguration(
style: const TextStyle(
color: AppColors.primaryBlue,
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
controller: txtSearch,
onChanged: (value) {
setState(() {
hasText = true;
});
},
decoration: InputDecoration(
prefixIcon: const Icon(
Icons.search,
color: AppColors.primaryBlue,
),
suffixIcon: showHideIcon(),
hintText: 'Search Stokvel',
border: const OutlineInputBorder(
borderSide:
BorderSide(color: AppColors.primaryBlue),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(4.0),
borderSide:
const BorderSide(color: AppColors.primaryBlue),
),
),
),
validator: (val) {
if (val!.isEmpty) {
return "Please select stokvel";
}
return null;
},
suggestionsCallback: BankingAppApi.getStokvelSuggestions,
itemBuilder: (context, Stokvel? suggestion) {
final stokvel = suggestion!;
//
return ListTile(
trailing: SizedBox(
height: 20.0,
width: 20.0,
child: Container(
color: AppColors.primaryBlue,
),
),
title: Text(
stokvel.stokvelName!,
style: const TextStyle(
fontFamily: Fonts.primaryFont,
fontWeight: FontWeight.bold,
color: AppColors.primaryBlue,
),
),
subtitle: Text(
stokvel.stokvelType!,
style: const TextStyle(
fontFamily: Fonts.primaryFont,
fontWeight: FontWeight.bold,
color: AppColors.primaryBlue),
),
);
},
noItemsFoundBuilder: (context) => const SizedBox(
height: 60,
child: Center(
child: Text(
'No Stokvel Found.',
style: TextStyle(fontSize: 20),
),
),
),
onSuggestionSelected: (Stokvel? suggestion) {
final stokvel = suggestion!;
setState(() {
txtSearch.text = stokvel.stokvelName!;
hasText = true;
});
stokvelID = stokvel.stokvelID;
memberID = stokvel.memberID;
},
),
),
SizedBox(
height: 4.h,
),
SizedBox(height: 3.h),
Container(
height: 6.h,
width: 98.w,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: TextFormField(
controller: txtAmount,
decoration: const InputDecoration(
labelStyle: TextStyle(
color: AppColors.primaryBlue,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
suffixText: "ZAR",
border: OutlineInputBorder(
borderSide:
BorderSide(color: AppColors.primaryBlue)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
labelText: 'Amount',
contentPadding:
EdgeInsets.only(left: 20, right: 15, bottom: 8),
),
keyboardType: TextInputType.number,
style: const TextStyle(
fontSize: 20.0,
fontFamily: Fonts.primaryFont,
color: AppColors.primaryBlue),
validator: (val) {
if (val!.isEmpty) {
return "Please enter amount";
}
return null;
},
),
),
SizedBox(height: 3.h),
Container(
height: 6.h,
width: 98.w,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: TextField(
readOnly: true,
style: const TextStyle(
fontSize: 18.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: "Wallet Balance : R " + mf().output.nonSymbol,
border: const OutlineInputBorder(
borderSide:
BorderSide(color: AppColors.primaryBlue),
borderRadius: BorderRadius.horizontal()),
focusedBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
),
),
),
SizedBox(height: 3.h),
Container(
height: 50,
width: 400,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white)),
child: isLoading
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CircularProgressIndicator(
color: AppColors.secondaryColor),
SizedBox(width: 24),
Text(
"Submitting payment...",
style: TextStyle(
color: AppColors.secondaryColor),
)
],
)
: Text(
buttonText,
style: const TextStyle(
fontFamily: Fonts.primaryFont,
fontWeight: FontWeight.bold,
color: AppColors.primaryBlue),
),
onPressed: () {
if (_formKey.currentState!.validate()) {
if (double.parse(txtAmount.text) <= balance!) {
setState(
() {
isLoading = true;
},
);
stokvelTransact.amount =
double.parse(txtAmount.text);
stokvelTransact.memberID = memberID;
stokvelTransact.stokvelID = stokvelID;
stokvelTransact.transactionTypeID = 1;
api
.stokvelDeposit(stokvelTransact,
"StokvelTransaction/StokvelTransact")
.then(
(value) => setState(
() {
Future.delayed(
const Duration(seconds: 3));
isLoading = false;
if (value == "Success") {
ScaffoldMessenger.of(context)
.showSnackBar(snackBar(
content:
'Payment made succesfully',
duration: 5));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(snackBar(
content:
'We have encountered technical problems, Try again later',
duration: 5));
}
},
),
)
.catchError(
(err) {
setState(() {
isLoading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
snackBar(
content: err.toString(), duration: 7));
},
);
} else {
ScaffoldMessenger.of(context).showSnackBar(snackBar(
content: "Insuficient funds!", duration: 7));
}
}
},
),
),
],
),
),
),
),
);
}
The above code is for the single page that I want to achieve this
This is what I want to achieve or any suggestions are accepted, I want to mark the Group of Stokvels I want to pay and pay them different accounts I don't know if it's possible please I'm new in flutter it a project I have to get it done as soon as possible this is the source code for my whole payment page, for now, I'm able to pay a single Stokvel Group but I want to select multiple
I highly suggest starting with formatting of the current code - its hard to read and with that hard to maintain.
The simple idea would be:
use List<StokvelDetail> selectedStokvel = []; you created to add the Stokvel's in every time you select Stokvel in SearchBar
Add Map<int,double> amounts = {}; <StokvelId, amount> to keep track of the amount you want to send to each Stokvel
Based on selectedStokvel build multiple 'amount window' widgets
Before submit verify walletBalance >= amounts.values.reduce((a,b)=> a + b)
For each selectedStokvel call api.stokvelDeposit(stokvelTransact, ...
I would primarly focus on spliting this code to multiple Widget classes, there are many schools but I like to have around 150 lines of code in single file at most.
From what i see your file can be easily split into:
Column(
children: [
SizedBox(),
SearchBar(),
SizedBox(),
AmountInput(), --> StokvelAmountInput() for each selectedStokvel
SizedBox(),
WalletBalance(),
SizedBox(),
SubmitButton(),
]),
```

I am making a contacts book application but when I save contacts the name is not displayed

This my contacts list page
class Contacts extends StatefulWidget with NavigationStates {
#override
_ContactsState createState() => _ContactsState();
}
class _ContactsState extends State<Contacts>{
DatabaseHelper databaseHelper = DatabaseHelper();
List<contacts> contactsList;
int count = 0;
#override
Widget build(BuildContext context, ) {
if(contactsList == 0){
contactsList = List<contacts>();
updateListView();
}
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text("Contacts"),
backgroundColor: Colors.lightGreenAccent,
centerTitle: true,
),
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(4.0),
margin: EdgeInsets.all(5.0),
child: TextField(
//controller: searchController,
decoration: InputDecoration(
labelText:'Search Contacts',
border: new OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(25)),
borderSide: new BorderSide(
color: Colors.pinkAccent
)
),
prefixIcon: Icon(
Icons.search,
color: Colors.black,
)
),
),
),
Expanded(
child: ListView.builder(
itemCount: count,
itemBuilder: (context , int position){
return Card(
elevation: 1.0,
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.pinkAccent,width: 1),
borderRadius: BorderRadius.circular(20)
),
child: Container(
margin: EdgeInsets.all(6.0),
padding: EdgeInsets.all(4.0),
color: Colors.white,
child: ListTile(
leading: CircleAvatar(
radius: 30.0,
backgroundColor: Colors.lightBlueAccent,
child: Icon(Icons.person,color: Colors.black,),
),
title: Text(this.contactsList[position].first_name,style: TextStyle(color: Colors.black,fontSize: 28.0),),
subtitle: Text(this.contactsList[position].last_name,style:TextStyle(color: Colors.black38,fontSize: 15.0),),
trailing: GestureDetector(
child: Icon(Icons.delete, color: Colors.pinkAccent,),
onTap: () {
_delete(context, contactsList[position]);
},
),
),
),
);
},
),
)
],
),
floatingActionButton: new FloatingActionButton(onPressed: null,
child: new Icon(Icons.dialpad,color: Colors.black,size: 30,),
backgroundColor: Colors.pinkAccent,
),
bottomNavigationBar: CurvedNavigationBar(
color: Colors.lightGreenAccent,
backgroundColor: Colors.white,
buttonBackgroundColor: Colors.pinkAccent,
height: 50,
index: 1,
items:<Widget>[
Icon(Icons.call,size: 25,color: Colors.black,),
Icon(Icons.home,size: 30,color: Colors.black,),
Icon(Icons.person_add_rounded,size: 25,color: Colors.black,),
],
animationDuration: Duration(
milliseconds: 400
),
animationCurve: Curves.easeIn,
onTap: (index) async {
if (index == 0)
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return logs();
}
)
);
if (index == 1)
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return Contacts();
}
)
);
if (index == 2)
navigateToDetail(contacts('',''));
}
),
);
}
updateListView() {
final Future<Database> dbFuture = databaseHelper.initalizeDatabase();
dbFuture.then((database) {
Future<List<contacts>> contactsListFuture = databaseHelper.getContactList();
contactsListFuture.then((contactsList){
setState(() {
this.contactsList = contactsList;
this.count = contactsList.length;
});
});
});
}
Color getStorageColor() {
int storage;
switch (storage) {
case 1:
return Colors.pinkAccent;
break;
case 2:
return Colors.lightBlueAccent;
break;
default:
return Colors.lightBlueAccent;
}
}
void navigateToDetail(contacts contact) async{
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) {
return AddContacts(contact);
}));
if (result == true) {
updateListView();
}
}
void _delete(BuildContext context, contacts contact) async {
int result = await databaseHelper.deleteContact(contact.id);
if (result != 0) {
_SnackBar(context, 'Contact Deleted Successfully');
updateListView();
}
}
void _SnackBar(BuildContext context, String message) {
final snackBar = SnackBar(
content: Text(message),
action: SnackBarAction(
label: 'Undo',
onPressed: (){},
),
);
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(snackBar);
}
}
This is my contacts details page
import 'dart:io';
//import 'package:contacts_service/contacts_service.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
//import 'package:sqflite/sqflite.dart';
import 'package:mycontacts_app/models/Contact.dart';
import 'dart:async';
import 'package:mycontacts_app/utils/database_helper.dart';
//import 'package:intl/intl.dart';
class AddContacts extends StatefulWidget {
final contacts contact;
AddContacts(this.contact);
//AddContacts(contacts contact);
#override
State<StatefulWidget> createState() {
// _AddContactsState();
return _AddContactsState(this.contact);
}
}
class _AddContactsState extends State<AddContacts> {
//TextEditingController _fnameController,_numberController,_lnameController;
DatabaseHelper helper = DatabaseHelper();
PickedFile _imageFile;
final ImagePicker _picker = ImagePicker();
_AddContactsState(this.contact);
TextEditingController _fnameController = TextEditingController();
TextEditingController _numberController = TextEditingController();
TextEditingController _lnameController = TextEditingController();
contacts contact;
List _Storage = ['Phone','Sim'];
//String _storageval;
#override
Widget build(BuildContext context) {
//_nameController = contacts.first_name
_fnameController.text = contact.first_name;
_lnameController.text = contact.last_name;
_numberController.text = contact.phone_no as String;
return Scaffold(
appBar: AppBar(
title: Text("New Contact"),
backgroundColor: Colors.lightGreenAccent,
centerTitle: true,
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(
vertical: 40.0,
horizontal: 10.0,
),
//margin: EdgeInsets.all(15),
child: Form(
child: Column(
//crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
padding: EdgeInsets.only(left: 16.0,right: 16.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.white
),
borderRadius: BorderRadius.circular(20.0),
),
child: DropdownButton(
hint: Text('Store In '),
dropdownColor: Colors.black12,
elevation: 5,
icon: Icon(Icons.arrow_drop_down),
iconSize: 20.0,
isExpanded: true,
style: TextStyle(
color: Colors.black,fontSize: 18.0
),
items: _Storage.map((value){
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
value: getStorageAsString(contact.storage),
onChanged: (value){
setState(() {
//_storageval = value;
updateStorageAsInt(value);
});
},
),
),
),
imageProfile(),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _fnameController,
onChanged: (value){
updateFirstname();
},
decoration: InputDecoration(
hintText: 'First Name',
prefixIcon: Icon(Icons.person),
//prefixText: "Name",
suffixIcon: Icon(Icons.keyboard_arrow_down),
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
contentPadding: EdgeInsets.all(15),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _lnameController,
onChanged: (value){
updateLastName();
},
decoration: InputDecoration(
hintText: 'Last Name',
prefixIcon: Icon(Icons.person),
//prefixText: "Name",
//suffixIcon: Icon(Icons.keyboard_arrow_down),
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
contentPadding: EdgeInsets.all(15),
),
),
),
// SizedBox(height: 15),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _numberController,
onChanged: (value){
//updateNumber();
},
decoration: InputDecoration(
hintText: 'Number',
prefixIcon: Icon(Icons.phone_android),
//prefixText: "Name",
//suffixIcon: Icon(Icons.keyboard_arrow_down),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
fillColor: Colors.white,
filled: true,
contentPadding: EdgeInsets.all(15),
),
),
),
//SizedBox(height: 15),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
//controller: _nameController,
decoration: InputDecoration(
hintText: 'Address',
prefixIcon: Icon(Icons.location_on_rounded),
//prefixText: "Name",
suffixIcon: Icon(Icons.keyboard_arrow_down),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
fillColor: Colors.white,
filled: true,
contentPadding: EdgeInsets.all(15),
),
),
),
//SizedBox(height: 15),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
//controller: _nameController,
decoration: InputDecoration(
hintText: 'Email',
prefixIcon: Icon(Icons.email),
//prefixText: "Name",
//suffixIcon: Icon(Icons.keyboard_arrow_down),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
fillColor: Colors.white,
filled: true,
contentPadding: EdgeInsets.all(15),
),
),
),
//SizedBox(height: 15),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
//controller: _nameController,
decoration: InputDecoration(
hintText: 'Website',
prefixIcon: Icon(Icons.language),
//prefixText: "Name",
//suffixIcon: Icon(Icons.keyboard_arrow_down),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
fillColor: Colors.white,
filled: true,
contentPadding: EdgeInsets.all(15),
),
),
),
//SizedBox(height: 15),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
//controller: _nameController,
decoration: InputDecoration(
hintText: 'Work Info',
prefixIcon: Icon(Icons.business),
//prefixText: "Name",
//suffixIcon: Icon(Icons.keyboard_arrow_down),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
fillColor: Colors.white,
filled: true,
contentPadding: EdgeInsets.all(15),
),
),
),
/*ListView.builder(
itemBuilder: (context, index){
return ExpansionTile(
title: ListTile(
title: TextField(
decoration: InputDecoration(
hintText: "Name"
),
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
),
),
),
children: <Widget>[
ListTile(
title:TextFormField(
decoration: InputDecoration(
hintText: "Name Prefix"
),
)
),
ListTile(
title:TextFormField(
decoration: InputDecoration(
hintText: " First Name"
),
)
),
ListTile(
title:TextFormField(
decoration: InputDecoration(
hintText: " Middle Name"
),
)
),
ListTile(
title:TextFormField(
decoration: InputDecoration(
hintText: "Last Name"
),
)
),
ListTile(
title:TextFormField(
decoration: InputDecoration(
hintText: "Name Suffix"
),
)
)
],
);
}
)*/
Padding(
padding: const EdgeInsets.only(top: 15.0, bottom: 15.0),
child: Row(
children: <Widget>[
Expanded(
child: RaisedButton(
color: Colors.lightGreenAccent,
textColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: BorderSide(color: Colors.pinkAccent),
),
onPressed: () {
debugPrint("Save button clicked");
_save();
},
child: Text(
"Save"
),
),
),
Container(width: 5.0,),
Expanded(
child: RaisedButton(
color: Colors.lightGreenAccent,
textColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: BorderSide(color: Colors.pinkAccent),
),
onPressed: () {
_delete();
},
child: Text(
"Cancel"
),
),
)
],
),
)
],
),
),
),
),
);
}
Widget imageProfile() {
return Center(
child: Stack(
children: <Widget>[
CircleAvatar(
radius: 50.0,
backgroundImage: _imageFile==null? AssetImage("assets/default.png"):FileImage(File(_imageFile.path)),
),
Positioned(
bottom: 20.0,
right: 20.0,
child: InkWell(
onTap: () {
showModalBottomSheet(
context: context,
builder: ((builder) => bottomSheet()),
);
},
child: Icon(
Icons.camera_alt,
color: Colors.lightGreenAccent,
size: 28.0,
),
),
),
],
),
);
}
Widget bottomSheet() {
return Container(
height: 100.0,
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(
horizontal: 20,
vertical: 20,
),
child: Column(
children: <Widget>[
Text(
"Choose Contact Image",
style: TextStyle(
fontSize: 20,
),
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton.icon(
icon: Icon(Icons.camera),
onPressed: (){
takePhoto(ImageSource.camera);
},
label: Text("Camera"),
),
FlatButton.icon(
icon: Icon(Icons.image),
onPressed: (){
takePhoto(ImageSource.gallery);
},
label: Text("Gallery"),
)
],
)
],
),
);
}
void takePhoto(ImageSource source) async {
final pickedFile = await _picker.getImage(
source: source,
);
setState(() {
_imageFile = pickedFile;
});
}
void updateFirstname(){
contact.first_name = _fnameController.text;
}
// Update the description of Note object
void updateLastName() {
contact.last_name = _lnameController.text;
}
/*void updateNumber() {
contact.phone_no = _numberController.text as int;
}*/
void _save() async {
moveToLastScreen();
//n.date = DateFormat.yMMMd().format(DateTime.now());
int result;
if (contact.id != null) { // Case 1: Update operation
result = await helper.updateContact(contact);
} else { // Case 2: Insert Operation
result = await helper.insertContact(contact);
}
if (result != 0) { // Success
_showAlertDialog('Status', 'Contact Saved Successfully');
} else { // Failure
_showAlertDialog('Status', 'Problem Saving Contact');
}
}
void moveToLastScreen() {
//Navigator.pop(context);
Navigator.pop(context, true);
}
void _delete() async {
moveToLastScreen();
// Case 1: If user is trying to delete the NEW NOTE i.e. he has come to
// the detail page by pressing the FAB of NoteList page.
if (contact.id == null) {
_showAlertDialog('Status','No Contact was deleted');
return;
}
// Case 2: User is trying to delete the old note that already has a valid ID.
int result = await helper.deleteContact(contact.id);
if (result != 0) {
_showAlertDialog('Status','Contact Deleted Successfully');
} else {
_showAlertDialog('Status', 'Error Occured while Deleting Contact');
}
}
void _showAlertDialog(String title, String message) {
AlertDialog alertDialog = AlertDialog(
title: Text(title),
content: Text(message),
);
showDialog(
context: context,
builder: (_) => alertDialog
);
}
void updateStorageAsInt(String value) {
switch (value) {
case 'Phone':
contact.storage = 1;
break;
case 'Sim':
contact.storage = 2;
break;
}
}
// Convert int priority to String priority and display it to user in DropDown
String getStorageAsString(int value) {
String storage;
switch (value) {
case 1:
storage = _Storage[0]; // 'High'
break;
case 2:
storage = _Storage[1]; // 'Low'
break;
}
return storage;
}
}
The contact card and icon is displayed but the name is not displaying.
I was even getting error like :-
This widget has been unmounted, so the State no longer has a context (and should be considered defunct).
It is not even showing the position or file of error
And I am not being able to solve the error .

Flutter show error when Password not match

I want to validate the passwords. The Widget _buildRepeatPasswordTF, has a TextFormField that validates if the value is not equal to the controller from _buildPasswordTF().
Widget _buildPasswordTF() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: < Widget > [
Container(
alignment: Alignment.centerLeft,
decoration: kBoxDecorationStyle,
height: 60.0,
child: TextField(
controller: _passwordController,
obscureText: true,
style: TextStyle(
color: Color.fromRGBO(0, 128, 128, 1),
fontFamily: 'OpenSans',
),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 14.0),
prefixIcon: Icon(
Icons.lock,
color: Color.fromRGBO(0, 128, 128, 1),
),
hintText: 'Password',
hintStyle: kHintTextStyle,
),
),
),
],
);
}
Widget _buildRepeatPasswordTF() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
decoration: kBoxDecorationStyle,
height: 60.0,
child: TextFormField(
controller: _repeatPasswordController,
obscureText: true,
style: TextStyle(
color: Color.fromRGBO(0, 128, 128, 1),
fontFamily: 'OpenSans',
),
validator: (value) {
if (value != _passwordController.text) {
return 'The password doesnt match';
}
return null;
},
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 14.0),
prefixIcon: Icon(
Icons.lock,
color: Color.fromRGBO(0, 128, 128, 1),
),
hintText: 'Repeat password',
hintStyle: kHintTextStyle,
),
),
),
],
);
}
Widget _buildSignUpBtn() {
return Container(
padding: EdgeInsets.symmetric(vertical: 25.0),
width: double.infinity,
child: RaisedButton(
elevation: 5.0,
onPressed: () async {
var password = _passwordController.text;
var email = _emailController.text;
var nom = _nameController.text;
var cognoms = _cognomsController.text;
try {
var r = await _provider.attemptSignUp(email, password, nom, cognoms, interessos, sexe, dataNeixement);
if(r['success'] == false) {
displayDialog(context, "Error", r['data']['message']);
}
else {
displayDialog(context, "Registrat", "Verifica el correu.").then((val) {
Navigator.of(context).pop();
});
}
} catch (err) {
displayDialog(context, "Error", err.response.toString());
}
},
padding: EdgeInsets.all(15.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: Color.fromRGBO(0, 128, 128, 1),
child: Text(
'Registrar-se',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'OpenSans',
),
),
),
);
}
You have missed a main Form and GlobalKeys.
Here a complete functional sample:
import 'package:flutter/material.dart';
class Password extends StatefulWidget {
#override
_PasswordState createState() => _PasswordState();
}
class _PasswordState extends State<Password> {
final TextEditingController _password = TextEditingController();
final TextEditingController _confirmPassword = TextEditingController();
final GlobalKey<FormState> _form = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(30),
child: Form(
key: _form,
child: Column(children: <Widget>[
TextFormField(
controller: _password,
validator: (validator) {
if (validator.isEmpty) return 'Empty';
return null;
}),
TextFormField(
controller: _confirmPassword,
validator: (validator) {
if (validator.isEmpty) return 'Empty';
if (validator != _password.text)
return 'The passwords do not match';
return null;
}),
RaisedButton(
child: Text(
'Registrar-se',
),
elevation: 5.0,
onPressed: () async {
_form.currentState.validate();
})
])),
);
}
}
I also have made a validation more sophisticated using RxDart and Streams. Check it out on medium