Flutter default profile picture for signup with u8intlist - flutter

The code below is my signup code, it has everything that I need but I got a problem with the default image. I made the connection with firebase but now I need to insert a default picture if the person doesn't chose a profile picture. What is the best way to tackle this?
I use de imagepicker to pick a picture from your own gallery, that is used in a async function called selectimage()
Then the async signup function is the function where the authmethods().signUpUser takes place. In this function it will then say that _image is null and that I can't use the ! operator.
import 'dart:typed_data';
import 'package:event_app/pages/Login_Page.dart';
import 'package:event_app/resources/auth_methods.dart';
import 'package:event_app/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:image_picker/image_picker.dart';
import '../utils/colors.dart';
import '../widgets/text_field_input.dart';
import '../widgets/password_field_input.dart';
import 'Verify_Email_Page.dart';
class SignupPage extends StatefulWidget {
const SignupPage({Key? key}) : super(key: key);
#override
_SignupPageState createState() => _SignupPageState();
}
class _SignupPageState extends State<SignupPage> {
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _usernameController = TextEditingController();
bool _isLoading = false;
Uint8List? _image;
#override
void dispose() {
super.dispose();
_emailController.dispose();
_passwordController.dispose();
_usernameController.dispose();
}
void selectImage() async {
Uint8List im = await pickImage(ImageSource.gallery);
setState(() {
_image = im;
});
}
void signUpUser() async {
setState(() {
_isLoading = true;
});
String res = await AuthMethods().signUpUser(
email: _emailController.text,
password: _passwordController.text,
username: _usernameController.text,
file: _image!);
if (res == "Success") {
setState(() {
_isLoading = false;
});
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const VerifyEmailPage()));
} else {
setState(() {
_isLoading = false;
});
showSnackBar(res, context);
}
}
void navigateToLogin() {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => const LoginPage()));
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 32),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
child: Container(),
flex: 2,
),
SvgPicture.asset(
'assets/ic_instagram.svg',
color: textColor,
height: 64,
),
const SizedBox(
height: 64,
),
Stack(
children: [
_image != null
? CircleAvatar(
radius: 64,
backgroundImage: MemoryImage(_image!),
backgroundColor: Colors.grey,
)
: const CircleAvatar(
radius: 64,
backgroundImage: NetworkImage(
'https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png'),
backgroundColor: Colors.grey,
),
Positioned(
bottom: -10,
left: 80,
child: IconButton(
onPressed: selectImage,
icon: const Icon(Icons.add_a_photo)))
],
),
const SizedBox(
height: 24,
),
TextFieldInput(
hintText: 'Enter your username',
textInputType: TextInputType.text,
textEditingController: _usernameController,
),
const SizedBox(
height: 24,
),
TextFieldInput(
hintText: 'Enter your email',
textInputType: TextInputType.emailAddress,
textEditingController: _emailController,
),
const SizedBox(
height: 24,
),
PasswordFieldInput(
hintText: 'Enter your password',
textInputType: TextInputType.text,
textEditingController: _passwordController,
),
const SizedBox(
height: 24,
),
InkWell(
child: Container(
child: !_isLoading
? const Text('Sign up')
: const Center(
child: CircularProgressIndicator(
color: textColor,
),
),
width: double.infinity,
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: const ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
),
color: accentColor,
),
),
onTap: signUpUser,
),
SizedBox(
height: 12,
),
Flexible(
child: Container(),
flex: 2,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: const Text("Already have an account?"),
padding: const EdgeInsets.symmetric(vertical: 8),
),
GestureDetector(
onTap: navigateToLogin,
child: Container(
child: const Text(
"Login.",
style: TextStyle(fontWeight: FontWeight.bold),
),
padding: const EdgeInsets.symmetric(vertical: 8),
),
)
],
),
],
),
)),
);
}
}

What if you change the selectImage function from async to sync function to prevent api call before _image is set.
void selectImage(){
pickImage(ImageSource.gallery).then(
(im){
setState(() {
_image = im;
});
});
}

Related

Flutter - bottomModalSheet can't validate a textfield widget

I have attached a project which is having a bottom modal sheet. Which sheet contains three TextField as name, number and email. So here I have implemented CRUD (Create, read, update and delete) operation and it's fine working. But without validating the TextField it shows in the HomePage. although if I miss to enter name or number still it's passing the data to the homepage card. I have tried many validating options but didn't worked out. If anyone can please help me.
My code:
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<Map<String, dynamic>> _contacts = [];
bool _isLoading = true;
final bool _validatename = true;
final bool _validatenumber = true;
final bool _validateemail = true;
void _refreshContacts() async {
final data = await Contact.getContacts();
setState(() {
_contacts = data;
_isLoading = false;
});
}
#override
void initState() {
super.initState();
_refreshContacts();
}
final _nameController = TextEditingController();
final _numberController = TextEditingController();
final _emailController = TextEditingController();
final bool _validate = false;
void _showForm(int? id) async {
if (id != null) {
final existingContact = _contacts.firstWhere((element) => element['id'] ==id);
_nameController.text = existingContact['name'];
_numberController.text = existingContact['number'];
_emailController.text = existingContact['email'];
}
showModalBottomSheet(context: context,
elevation: 5,
isScrollControlled: true,
builder: (_) => Container(
padding: EdgeInsets.only(top: 15, left: 15, right: 15, bottom: MediaQuery.of(context).viewInsets.bottom + 120),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
controller: _nameController,
decoration: const InputDecoration(
hintText: "Name",
),
),
const SizedBox(
height: 10.0,
),
TextField(
keyboardType: TextInputType.number,
controller: _numberController,
decoration: const InputDecoration(
hintText: "Numbers",
),
),
const SizedBox(
height: 10.0,
),
TextField(
// keyboardType: TextInputType.emailAddress,
controller: _emailController,
decoration: const InputDecoration(
hintText: "Email Address",
),
),
const SizedBox(
height: 20.0,
),
Row(
children: [
ElevatedButton(
onPressed: () async {
if (id == null) {
await _addContact();
}
if (id != null) {
await _updateContact(id);
}
Navigator.of(context).pop();
_nameController.text = '';
_numberController.text = '';
_emailController.text = '';
},
child: Text(id == null ? 'Create New' : 'Update'),
),
const SizedBox(
width: 10.0,
),
ElevatedButton(onPressed: () async {
_nameController.text = '';
_numberController.text = '';
_emailController.text = '';
}, child: const Text("Clear")),
const SizedBox(
width: 10.0,
),
ElevatedButton(onPressed: (){
Navigator.pop(context);
}, child: const Text("Go Back")),
],
),
]),
));
}
Future<void> _addContact() async {
await Contact.createContact(
_nameController.text, _numberController.text, _emailController.text
);
_refreshContacts();
}
Future<void> _updateContact(int id) async {
await Contact.updateContact(id, _nameController.text, _numberController.text, _emailController.text );
_refreshContacts();
}
void _deleteContact(int id) async {
await Contact.deleteContact(id);
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Sccessfully Contact Deleted")));
_refreshContacts();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Contact App",),
backgroundColor: Colors.blueAccent,
centerTitle: true,
toolbarHeight: 80,
),
body: _isLoading ? const Center(child: CircularProgressIndicator(),) :
ListView.builder(
itemCount: _contacts.length,
itemBuilder: (context, index) =>
Card(
elevation: 5,
shape: const Border(
right: BorderSide(color: Colors.blue, width: 10.0),
),
color: Colors.orange[200],
margin: const EdgeInsets.all(15.0),
child: Material(
elevation: 20.0,
shadowColor: Colors.blueGrey,
child: ListTile(
title: Text(_contacts[index]['name'], style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold),),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(_contacts[index]['number'], style: const TextStyle(color: Colors.grey, fontSize: 18),),
const SizedBox(
height: 5.0,
),
Text(_contacts[index]['email'], style: const TextStyle(fontSize: 17, color: Colors.black),),
],
),
trailing: SizedBox(
width: 100,
child: Row(
children: [
IconButton(onPressed: () => _showForm(_contacts[index]['id']), icon: const Icon(Icons.edit, color: Colors.blueGrey,)),
IconButton(onPressed: () => _deleteContact(_contacts[index]['id']), icon: const Icon(Icons.delete, color: Colors.red,)),
],
),
),
),
),
),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add, size: 28,),
onPressed: () => _showForm(null),
),
);
}
}
Above codes are from homepage. I need only the validating part + if anyone can know how to show the each card in another page using page route. Actually this is a contact app. I have tried the new screen to show the full details but couldn't.
You can return when any of the field is empty like
ElevatedButton(
onPressed: () async {
if (_nameController.text.isEmpty ||
_numberController.text.isEmpty ||
_emailController.text.isEmpty) {
return;
}
},
child: Text(id == null ? 'Create New' : 'Update'),
),
But it will be better to use Form widget TextFormFiled with validator . Find more on validation
final _formKey = GlobalKey<FormState>();
showModalBottomSheet(
context: context,
elevation: 5,
isScrollControlled: true,
builder: (_) => Container(
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
controller: _nameController,
decoration: const InputDecoration(
hintText: "Name",
),
),
Row(
children: [
ElevatedButton(
onPressed: () async {
final isValided =
_formKey.currentState?.validate();
if (isValided == true) {}
},
child: Text(id == null ? 'Create New' : 'Update'),
),

New to flutter and unsure how to solve this error: Exception has occurred. LateError

Getting the error message: 'Exception has occurred.
LateError (LateInitializationError: Field 'selectedImage' has not been initialized'
Anyone know how I can solve this?
Been following a tutorial to build an app that I can add photos to but got a bit stuck on this part.
using firebase storage to store the photos, as far as I can tell thats been set up correctly.
thanks.
class CreateBlog extends StatefulWidget {
const CreateBlog({Key? key}) : super(key: key);
#override
State<CreateBlog> createState() => _CreateBlogState();
}
class _CreateBlogState extends State<CreateBlog> {
String? authorName, title, desc;
File? selectedImage;
CrudMethods crudMethods = CrudMethods();
Future getImage() async {
var image = await ImagePicker().pickImage(source: ImageSource.camera);
setState(() {
selectedImage = image as File;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text(
'Travel',
style: TextStyle(fontSize: 22),
),
Text('Blog', style: TextStyle(fontSize: 22, color: Colors.green))
],
),
backgroundColor: Colors.transparent,
elevation: 0.0,
actions: <Widget>[
GestureDetector(
onTap: () {
getImage();
},
child: selectedImage != null
? Container(
height: 150,
width: MediaQuery.of(context).size.width,
child: Image.file(selectedImage),
margin: const EdgeInsets.symmetric(horizontal: 16),
)
: Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
child: const Icon(Icons.add))),
],
),
body: Container(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
children: <Widget>[
const SizedBox(height: 12),
Container(
height: 150,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(6),
),
width: MediaQuery.of(context).size.width,
child: const Icon(Icons.add_a_photo, color: Colors.black45)),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: <Widget>[
TextField(
decoration: const InputDecoration(hintText: 'Author Name'),
onChanged: (val) {
authorName = val;
},
),
TextField(
decoration: const InputDecoration(hintText: 'Title'),
onChanged: (val) {
title = val;
},
),
TextField(
decoration:
const InputDecoration(hintText: 'Description'),
onChanged: (val) {
desc = val;
}),
],
),
)
],
),
),
);
}
}
It is possible to get null value from pickedImage, Try accepting null value.
Future getImage() async {
XFile? image = await ImagePicker().pickImage(source: ImageSource.camera);
if (image != null) {
setState(() {
selectedImage = image;
});
}
}
And use
child: selectedImage != null
? Container(
height: 150,
width: MediaQuery.of(context).size.width,
child: Image.file(File(selectedImage!.path)),
margin: const EdgeInsets.symmetric(horizontal: 16),
)
The error really implies that you wrote
late File? selectedImage;
instead of
File? selectedImage;
so I think you showed us the wrong code. Leaving out late should solve this.
Let me know whether it is working for you.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class CreateBlog extends StatefulWidget {
const CreateBlog({Key? key}) : super(key: key);
#override
State<CreateBlog> createState() => _CreateBlogState();
}
class _CreateBlogState extends State<CreateBlog> {
String? authorName, title, desc;
XFile? selectedImage;
getImage() async {
try {
final XFile? pickedImage =
await ImagePicker().pickImage(source: ImageSource.gallery);
if (pickedImage != null) {
setState(() {
selectedImage = pickedImage;
});
}
} catch (e) {
debugPrint(e.toString());
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text(
'Travel',
style: TextStyle(fontSize: 22),
),
Text('Blog', style: TextStyle(fontSize: 22, color: Colors.black))
],
),
backgroundColor: Colors.grey,
elevation: 0.0,
),
body: Container(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
children: <Widget>[
const SizedBox(height: 12),
GestureDetector(
onTap: () {
getImage();
},
child: selectedImage != null
? Container(
height: 150,
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.symmetric(horizontal: 16),
child: Image.file(File(selectedImage!.path)),
)
: Container(
height: 150,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(6),
),
width: MediaQuery.of(context).size.width,
child:
const Icon(Icons.add_a_photo, color: Colors.black45)),
),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: <Widget>[
TextField(
decoration: const InputDecoration(hintText: 'Author Name'),
onChanged: (val) {
authorName = val;
},
),
TextField(
decoration: const InputDecoration(hintText: 'Title'),
onChanged: (val) {
title = val;
},
),
TextField(
decoration:
const InputDecoration(hintText: 'Description'),
onChanged: (val) {
desc = val;
}),
],
),
)
],
),
),
);
}
}

Why is Flutter BloC UI not updating after app restart despite state change in observer?

I concede that there are many questions similar to mine, but I have not found a satisfactory answer from those questions. So I decided to make my own question specifying my problem. I have 3 BloCs in my program each with different purposes. They all share similar problems, as such I will ask on one of those BloCs with the hope that one solution will fix all of the BloCs.
The problem is this, if I just started the application and have logged in, the BloC will update the UI. If I have logged in, exited the app, and restarted it, the Bloc will not update the UI. The Bloc in question is called DetailpersonilBloc with 1 event called Detail and 2 states called DetailpersonilInitial and Loaded. At the event of Detail, the state Loaded should be emitted.
I called Detail at LoginPage and at GajiPage at initState. This works when I just opened the app, but does not work when I restart the app. I also have equatable thinking that it will help me but apparently it changes nothing.
Note: The "..." at the GajiPage is just some code that I believe is not necessary for reproduction.
DetailpersonilBloc
part 'detailpersonil_event.dart';
part 'detailpersonil_state.dart';
class DetailpersonilBloc
extends Bloc<DetailpersonilEvent, DetailpersonilState> {
DetailpersonilBloc() : super(const DetailpersonilInitial()) {
on<Detail>((event, emit) async {
SharedPreferences pref = await SharedPreferences.getInstance();
String name = pref.getString('nama');
String nrp = pref.getString('NRP');
String pangkat = pref.getString('pangkat');
String jabatan = pref.getString('jabatan');
String satker = pref.getString('satker');
String polda = pref.getString('polda');
String npwp = pref.getString('NPWP');
String rekening = pref.getString('rekening');
String bank = pref.getString('bank');
emit(Loaded(
name,
nrp,
pangkat,
jabatan,
satker,
polda,
npwp,
rekening,
bank,
));
});
}
}
DetailpersonilEvent
part of 'detailpersonil_bloc.dart';
#immutable
abstract class DetailpersonilEvent extends Equatable {}
class Detail extends DetailpersonilEvent {
#override
List<Object> get props => [];
}
DetailpersonilState
part of 'detailpersonil_bloc.dart';
#immutable
abstract class DetailpersonilState extends Equatable {
final String nama;
final String nrp;
final String pangkat;
final String jabatan;
final String satker;
final String polda;
final String npwp;
final String rekening;
final String bank;
const DetailpersonilState(
{this.nama,
this.nrp,
this.pangkat,
this.jabatan,
this.satker,
this.polda,
this.npwp,
this.rekening,
this.bank});
}
class DetailpersonilInitial extends DetailpersonilState {
const DetailpersonilInitial()
: super(
nama: 'Nama',
nrp: 'NRP',
pangkat: 'Pangkat',
jabatan: 'Jabatan',
satker: 'Satker',
polda: 'Polda',
npwp: 'NPWP',
rekening: 'No Rekening',
bank: 'Nama Bank',
);
#override
List<Object> get props =>
[nama, nrp, pangkat, jabatan, satker, polda, npwp, rekening, bank];
}
class Loaded extends DetailpersonilState {
const Loaded(
String nama,
String nrp,
String pangkat,
String jabatan,
String satker,
String polda,
String npwp,
String rekening,
String bank,
) : super(
nama: nama,
nrp: nrp,
pangkat: pangkat,
jabatan: jabatan,
satker: satker,
polda: polda,
npwp: npwp,
rekening: rekening,
bank: bank);
#override
List<Object> get props =>
[nama, nrp, pangkat, jabatan, satker, polda, npwp, rekening, bank];
}
LoginPage
class LoginPage extends StatefulWidget {
const LoginPage({Key key}) : super(key: key);
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
double width = 0;
double height = 0;
TextEditingController nrpController = TextEditingController();
TextEditingController sandiController = TextEditingController();
final formKey = GlobalKey<FormState>();
DetailpersonilBloc detailPersonilBloc;
GajiBloc gajiBloc;
TunkinBloc tunkinBloc;
bool passwordVisible = false;
#override
void initState() {
super.initState();
checkToken();
}
void checkToken() async {
SharedPreferences pref = await SharedPreferences.getInstance();
if (pref.getString('token') != null) {
detailPersonilBloc = DetailpersonilBloc();
gajiBloc = GajiBloc();
tunkinBloc = TunkinBloc();
detailPersonilBloc.add(Detail());
gajiBloc.add(Gaji());
tunkinBloc.add(Tunkin());
Navigator.push(
context, MaterialPageRoute(builder: (context) => const MainPage()));
}
}
onLogin(DetailpersonilBloc detailPersonilBloc) async {
if (formKey.currentState.validate()) {
var token = await APIService.generateToken(
nrpController.text, sandiController.text);
if (token != null) {
SharedPreferences pref = await SharedPreferences.getInstance();
await pref.setString('token', token.token);
var detail = await APIService.getDetailPersonil(token.token);
await pref.setString('nama', detail.nMPEG);
await pref.setString('NRP', detail.nRP);
await pref.setString('pangkat', detail.nMGOL1);
await pref.setString('jabatan', detail.sEBUTJAB);
await pref.setString('satker', detail.nMSATKER);
await pref.setString('polda', detail.nMUAPPAW);
await pref.setString('NPWP', detail.nPWP);
await pref.setString('rekening', detail.rEKENING);
await pref.setString('bank', detail.nMBANK);
nrpController.clear();
sandiController.clear();
detailPersonilBloc.add(Detail());
Navigator.push(
context, MaterialPageRoute(builder: (context) => const MainPage()));
} else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Error'),
content: Text('Login Gagal'),
actions: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('Tutup'),
),
],
);
},
);
}
}
}
#override
Widget build(BuildContext context) {
var detailPersonilBloc = BlocProvider.of<DetailpersonilBloc>(context);
width = MediaQuery.of(context).size.width;
height = MediaQuery.of(context).size.height;
return Scaffold(
body: Stack(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: const [
Opacity(
opacity: 0.5,
child: Image(
image: AssetImage('images/bg-map-min.png'),
),
),
],
),
SingleChildScrollView(
padding: EdgeInsets.only(top: 100),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 100,
width: width,
child: const Image(
image: AssetImage('images/login-logo.png'),
alignment: Alignment.center,
),
),
Container(
padding: const EdgeInsets.all(15),
child: const Text(
'GAJI DAN TUNKIN',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
Form(
key: formKey,
child: Column(
children: [
Container(
margin: const EdgeInsets.all(20 - 2.6),
child: Card(
elevation: 10,
child: Container(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Container(
alignment: Alignment.topLeft,
padding: const EdgeInsets.only(bottom: 20),
child: const Text(
'LOGIN',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
Container(
padding: const EdgeInsets.only(bottom: 25),
child: TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan NRP/NIP';
}
return null;
},
controller: nrpController,
decoration: InputDecoration(
labelText: 'NRP/NIP',
hintText: 'Masukkan NRP/NIP',
prefixIcon: Icon(Icons.person,
color: Colors.blue.shade700),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
),
TextFormField(
obscureText: !passwordVisible,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan Kata Sandi';
}
return null;
},
controller: sandiController,
decoration: InputDecoration(
labelText: 'Kata Sandi',
hintText: 'Masukkan Kata Sandi',
prefixIcon: Icon(Icons.lock,
color: Colors.blue.shade700),
suffixIcon: IconButton(
onPressed: () {
setState(() {
passwordVisible = !passwordVisible;
});
},
icon: Icon(
passwordVisible
? Icons.visibility
: Icons.visibility_off,
color: Colors.blue.shade700,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
)
],
),
),
),
),
ElevatedButton(
onPressed: () async {
await onLogin(detailPersonilBloc);
},
child: const Text('LOGIN'),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade700,
minimumSize: const Size(200, 40),
),
)
],
),
),
],
),
),
],
),
);
}
}
GajiPage
class GajiPage extends StatefulWidget {
const GajiPage({Key key}) : super(key: key);
#override
_GajiPageState createState() => _GajiPageState();
}
class _GajiPageState extends State<GajiPage> {
double width = 0;
double height = 0;
var currentYear = DateTime.now().year;
var currentMonth = DateTime.now().month;
DetailpersonilBloc detailPersonilBloc;
GajiBloc gajiBloc;
#override
void initState() {
setState(() {
detailPersonilBloc = DetailpersonilBloc();
detailPersonilBloc.add(Detail());
setMonth();
setYear();
gajiBloc = GajiBloc();
gajiBloc.add(Gaji());
});
super.initState();
}
#override
Widget build(BuildContext context) {
var detailPersonilBloc = BlocProvider.of<DetailpersonilBloc>(context);
width = MediaQuery.of(context).size.width;
height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Image(
image: const AssetImage('images/header-logo.png'),
width: width / 2,
),
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Color.fromARGB(255, 170, 177, 175),
Color.fromARGB(255, 197, 217, 212)
],
),
),
),
),
body: Stack(
children: [
BlocBuilder<GajiBloc, GajiState>(
builder: (context, state) {
return state is GajiLoaded
? ListView(
children: [
Container(
height: 100,
),
Card(
color: const Color.fromARGB(255, 74, 50, 152),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.all(10),
child: const Text(
'Gaji Bersih',
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
),
Container(
margin: const EdgeInsets.all(10),
child: Text(
NumberFormat.currency(
locale: 'en',
symbol: 'RP ',
decimalDigits: 0)
.format(state.bersih),
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 40,
color: Colors.white,
),
),
),
],
),
),
Card(
child: Column(
children: [
Container(
color: const Color.fromARGB(255, 238, 238, 238),
width: width,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Container(
margin: const EdgeInsets.fromLTRB(
10, 10, 0, 10),
width: (width / 2) - 25,
child: const Text(
'Detail Gaji',
textAlign: TextAlign.start,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 20,
),
),
),
Container(
margin: const EdgeInsets.fromLTRB(
5, 10, 20, 10),
width: (width / 2) - 18,
child: Text(
'${state.bulan} - ${state.tahun}',
textAlign: TextAlign.end,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 20,
),
),
)
],
),
),
...
],
),
),
Container(
height: 50,
),
],
)
: Center(
child: Text(
'Tidak ada data. Data gaji bulan ${state.bulan} belum diproses'),
);
},
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Center(
child: BlocBuilder<DetailpersonilBloc, DetailpersonilState>(
builder: (context, state) {
return Card(
child: Row(
children: [
Container(
margin: const EdgeInsets.all(10),
child: const CircleAvatar(
backgroundImage: AssetImage('images/Profpic.PNG'),
radius: 30,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 250,
padding: const EdgeInsets.all(5),
child: Text(
state.nama,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
)),
Container(
padding: const EdgeInsets.all(5),
child: Text(
state.nrp,
style: const TextStyle(fontSize: 15),
)),
],
),
GestureDetector(
onTap: () {
detailPersonilBloc.add(Detail());
showModalBottomSheet(
backgroundColor: Colors.transparent,
isScrollControlled: true,
context: context,
builder: (context) => detailsBottomSheet(),
);
},
child: const Text(
'DETAILS',
style: TextStyle(color: Colors.blue),
),
)
],
),
);
},
),
),
GestureDetector(
onTap: () {
showModalBottomSheet(
backgroundColor: Colors.transparent,
isScrollControlled: true,
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, StateSetter setState) {
return filterBottomSheet();
},
);
},
);
},
child: Container(
height: 50,
width: width,
decoration: const BoxDecoration(
color: Color.fromARGB(255, 244, 244, 244),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.only(right: 3),
child: const Icon(
Icons.tune,
color: Color.fromARGB(255, 45, 165, 217),
),
),
const Text(
'Filter',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20,
color: Color.fromARGB(255, 45, 165, 217),
),
),
],
),
),
)
],
)
],
),
);
}
}
Note 2: The "..." is a bunch of code not needed for reproduction.
The answer is surprisingly simple as I would learn from my internship. The reason the Bloc is not updating is because I was not using the context of the application. So when I generated a new Bloc inside my pages, it was "empty". So the solution is to use context.read().add(BlocEvent()) or create a new bloc with BlocProvider.of(context) then add the event. Basically the bloc has to be provided with the original context of the application.

Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?

I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
My Code :
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_clipboard_manager/flutter_clipboard_manager.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'URL Shortener',
theme: ThemeData(
primarySwatch: Colors.purple,
),
home: StartPage(),
);
}
}
class StartPage extends StatefulWidget {
#override
_StartPageState createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
bool visibilityTag = false;
void _changed(bool visibility, String field) {
setState(() {
if (field == "tag") {
visibilityTag = visibility;
}
});
}
final GlobalKey<ScaffoldState> _globalKey = GlobalKey<ScaffoldState>();
String shortUrl = "";
String value = "";
String buttonText = "COPY!";
bool isChanged = true;
TextEditingController urlcontroller = TextEditingController();
getData() async {
var url = 'https://api.shrtco.de/v2/shorten?url=${urlcontroller.text}';
var response = await http.get(url);
var result = jsonDecode(response.body);
if (result['ok']) {
setState(() {
shortUrl = result['result']['short_link'];
});
} else {
print(response);
}
}
copy(String url) {
FlutterClipboardManager.copyToClipBoard(url).then((value) {});
}
buildRow(String data, bool original) {
return SingleChildScrollView(
child: original
? Container(
alignment: Alignment.center,
child: Text(
data,
))
: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
data,
),
ElevatedButton(
child: Text(buttonText),
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(300, 40),
),
onPressed: () {
copy(shortUrl);
setState(() {
if (isChanged == true) {
buttonText = "COPIED!";
}
});
},
),
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[300],
body: ListView(
children: [
SvgPicture.asset(
'assets/logo.svg',
),
SvgPicture.asset(
'assets/illustration.svg',
),
Center(
child: Text(
"Let's get started!",
style: TextStyle(
fontSize: 20,
color: Color.fromRGBO(53, 50, 62, 10),
fontWeight: FontWeight.bold),
),
),
Center(
child: SizedBox(
width: 200,
height: 60,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Paste your first link into the field to shorten it",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
color: Color.fromRGBO(76, 74, 85, 10),
fontWeight: FontWeight.bold)),
),
),
),
SizedBox(
height: 130,
child: Stack(
alignment: Alignment.center,
children: [
Container(
alignment: Alignment.centerRight,
color: Color.fromRGBO(59, 48, 84, 1),
child: SvgPicture.asset(
'assets/shape.svg',
color: Color.fromRGBO(75, 63, 107, 1),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 300,
height: 40,
child: TextField(
onChanged: (text) {
value = "URL : " + text;
},
controller: urlcontroller,
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
fillColor: Colors.white,
filled: true,
hintText: 'Shorten a link here ...'),
),
),
SizedBox(
height: 10,
),
SizedBox(
width: 300,
child: ElevatedButton(
onPressed: getData,
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(60, 40),
),
child: Text('SHORTEN IT!'),
),
),
],
),
],
),
),
Padding(
padding: const EdgeInsets.all(13.0),
child: Container(
color: Colors.white,
width: double.infinity,
child: Column(
children: [
SizedBox(
height: 10,
),
buildRow(value, true),
buildRow(shortUrl, false),
],
),
),
)
],
),
);
}
}
Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
On State create a bool like
bool showCopyButton = false;
Change to true at
SizedBox(
width: 300,
child: ElevatedButton(
onPressed: ()async {
print("Button Click");
await getData();
setState(() {
showCopyButton = true;
});
},
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(60, 40),
),
child: Text('SHORTEN IT!'),
),
),
And wrap with Visibility Like
Visibility(
visible: showCopyButton,
child: Padding(
padding: const EdgeInsets.all(13.0),
child: Container(
color: Colors.white,
width: double.infinity,
child: Column(
children: [
SizedBox(
height: 10,
),
buildRow("Text ", true),
buildRow("asdad", false),
],
),
),
),
)
or you can just if like
if (showCopyButton)
Padding(
padding: const EdgeInsets.all(13.0),
child: Container(
color: Colors.white,
width: double.infinity,
child: Column(
children: [
SizedBox(
height: 10,
),
buildRow("Text ", true),
buildRow("asdad", false),
],
),
),
),
Btw you need to use await before making it true.
Hope this helps:
import 'package:flutter/material.dart';
class Screen extends StatefulWidget {
#override
_ScreenState createState() => _ScreenState();
}
class _ScreenState extends State<Screen> {
bool _paddingVisible = false;
#override
void initState() {
super.initState();
Future.delayed(const Duration(seconds: 10), () {
// Check if mounted == true, because the screen might closed
// before 10 seconds pass
if (mounted) {
// Setting padding visibility to true after 10 seconds
setState(() {
_paddingVisible = true;
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
// All your widgets
// When _paddingVisible becomes true it will be displayed
if (_paddingVisible) SizedBox(height: 10),
],
),
);
}
}

PhotoURL was called on null error in flutter [duplicate]

This question already has answers here:
What is a NoSuchMethod error and how do I fix it?
(2 answers)
Closed 2 years ago.
In my flutter project, i used CachedNetworkImageProvider, in which i passed photo url, but it is showing me an error, that it is called on null. Can anyone help me please? Check out line 158. If you think, there is nothing wrong in this part, and some other widget is causing the error, (that are made by me), then please tell me, i will provide you that. Please help me. I am new to this thing.
Here's the exception -
The getter 'photoUrl' was called on null.
Receiver: null
Tried calling: photoUrl
The relevant error-causing widget was:
Upload file:///C:/Users/Hp/AndroidStudioProjects/social_app/lib/pages/home.dart:117:11
Here's the code -
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:social_app/models/users.dart';
class Upload extends StatefulWidget {
final User currentUser;
Upload({this.currentUser});
#override
_UploadState createState() => _UploadState();
}
class _UploadState extends State<Upload> {
File file;
handleTakePhoto() async {
Navigator.pop(context);
File file = await ImagePicker.pickImage(source: ImageSource.camera, maxWidth: 960, maxHeight: 675);
// ImagePicker imagePicker;
// PickedFile pickedFile = await imagePicker.getImage(source: ImageSource.camera, maxHeight: 675, maxWidth: 960);
// File file = File(pickedFile.path);
setState(() {
this.file = file;
});
}
handleChooseFromGallery() async{
Navigator.pop(context);
File file = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
this.file = file;
});
// ImagePicker imagePicker;
// PickedFile pickedFile = await imagePicker.getImage(source: ImageSource.gallery);
// File file = File(pickedFile.path);
// setState(() {
// this.file = file;
// });
}
selectImage(parentContext) {
return showDialog(
context: parentContext,
builder: (context) {
return SimpleDialog(
title: Text('Create Post'),
children: <Widget>[
SimpleDialogOption(
child: Text('Click Photo'),
onPressed: handleTakePhoto,
),
SimpleDialogOption(
child: Text('Import from Gallery'),
onPressed: handleChooseFromGallery,
),
SimpleDialogOption(
child: Text('Cancel'),
onPressed: () => Navigator.pop(context),
),
],
);
}
);
}
Container buildSplashScreen() {
return Container(
color: Colors.black54,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SvgPicture.asset('assets/images/upload.svg', height: 300.0,),
Padding(
padding: EdgeInsets.only(top: 40.0),
child: RaisedButton(
padding: EdgeInsets.all(10.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
child: Text(
'Upload Image',
style: TextStyle(
color: Colors.white,
fontSize: 30.0,
),
),
color: Colors.blueGrey[600],
onPressed: () => selectImage(context),
),
),
],
),
);
}
clearImage() {
setState(() {
file =null;
});
}
Scaffold buildUploadForm() {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white70,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black,),
onPressed: clearImage,
),
title: Center(
child: Text(
'Caption Post',
style: TextStyle(
color: Colors.black,
),
),
),
actions: [
FlatButton(
onPressed: () => print('Pressed'),
child: Text(
'Post',
style: TextStyle(
color: Colors.blueAccent,
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
),
),
],
),
body: ListView(
children: <Widget>[
Container(
height: 220.0,
width: MediaQuery.of(context).size.width * 0.8,
child: Center(
child: AspectRatio(
aspectRatio: 16/9,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: FileImage(file),
),
),
),
),
),
),
Padding(
padding: EdgeInsets.only(top: 10.0),
),
ListTile(
leading: CircleAvatar(
backgroundImage: CachedNetworkImageProvider(widget.currentUser.photoUrl),
),
title: Container(
width: 250.0,
child: TextField(
decoration: InputDecoration(
hintText: "Write a caption..",
border: InputBorder.none,
),
),
),
),
Divider(
),
ListTile(
leading: Icon(
Icons.pin_drop,
color: Colors.blue,
size: 36.0,
),
title: Container(
width: 250.0,
child: TextField(
decoration: InputDecoration(
hintText: 'Search a location...',
border: InputBorder.none,
),
),
),
),
Container(
width: 200.0,
height: 100.0,
alignment: Alignment.center,
child: RaisedButton.icon(
label: Text(
'Use current location...',
style: TextStyle(
color: Colors.white,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: Colors.blue,
onPressed: () => print('Get user location'),
icon: Icon(
Icons.my_location,
color: Colors.white,
),
),
),
],
),
);
}
#override
Widget build(BuildContext context) {
return file == null ? SafeArea(
child: Scaffold(
backgroundColor: Colors.black45,
body: buildSplashScreen(),
),
) : buildUploadForm();
}
}
home page -
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:social_app/pages/activity_feed.dart';
import 'package:social_app/pages/create_account.dart';
import 'package:social_app/pages/profile.dart';
import 'package:social_app/pages/search.dart';
import 'package:social_app/pages/timeline.dart';
import 'package:social_app/pages/upload.dart';
import 'package:social_app/widgets/header.dart';
import 'package:social_app/models/users.dart';
final GoogleSignIn googleSignIn = GoogleSignIn();
final usersRef = FirebaseFirestore.instance.collection('users');
final DateTime timeStamp = DateTime.now();
User currentUser;
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool isAuth = false;
PageController pageController;
int pageIndex=0;
#override
void initState(){
super.initState();
pageController = PageController(initialPage: 0);
googleSignIn.onCurrentUserChanged.listen((account) {
handleSignIn(account);
},
onError: (error) {
print("Error in signing in : $error");
});
googleSignIn.signInSilently(suppressErrors: false).then((account){
handleSignIn(account);
}).catchError((error){
print("Error in signing in : $error");
});
}
handleSignIn(GoogleSignInAccount account) {
if (account != null) {
createUserInFirestore();
setState(() {
isAuth = true;
});
}
else {
setState(() {
isAuth = false;
});
}
}
createUserInFirestore() async{
final GoogleSignInAccount user = googleSignIn.currentUser;
DocumentSnapshot doc = await usersRef.doc(user.id).get();
if(!doc.exists) {
final username = await Navigator.push(context, MaterialPageRoute(builder: (context) => CreateAccount()));
usersRef.doc(user.id).set({
"id" : user.id,
"username" : username,
"photoUrl" : user.photoUrl,
"email" : user.email,
"displayName" : user.displayName,
"bio" : "",
"timeStamp" : timeStamp,
});
}
}
#override
void dispose() {
pageController.dispose();
super.dispose();
}
login() {
googleSignIn.signIn();
}
logout() {
googleSignIn.signOut();
}
onPageChanged(int pageIndex) {
setState(() {
this.pageIndex = pageIndex;
});
}
onTap(int pageIndex) {
pageController.animateToPage(
pageIndex,
duration: Duration(milliseconds: 250),
curve: Curves.easeInOut,
);
}
Scaffold buildAuthScreen(){
return Scaffold(
body: PageView(
children: <Widget>[
//Timeline(),
RaisedButton(
onPressed: logout,
child: Text('logout'),
),
Search(),
Upload(currentUser: currentUser),
ActivityFeed(),
Profile(),
],
controller: pageController,
onPageChanged: onPageChanged,
physics: NeverScrollableScrollPhysics(),
),
bottomNavigationBar: CupertinoTabBar(
backgroundColor: Colors.black,
currentIndex: pageIndex,
onTap: onTap,
activeColor: Colors.white,
items: [
BottomNavigationBarItem(icon: Icon(Icons.home_filled)),
BottomNavigationBarItem(icon: Icon(Icons.search)),
BottomNavigationBarItem(icon: Icon(Icons.add_box_outlined)),
BottomNavigationBarItem(icon: Icon(Icons.favorite_border)),
BottomNavigationBarItem(icon: Icon(Icons.account_circle)),
],
),
);
// return RaisedButton(
// onPressed: logout,
// child: Text('logout'),
// );
}
Scaffold buildUnauthScreen() {
return Scaffold(
appBar: header(context, titleText: 'Instagram'),
backgroundColor: Colors.black,
body: SafeArea(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
Theme.of(context).primaryColor,
Colors.teal.withOpacity(1.0),
Colors.orange,
]
),
),
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'Technua',
style: GoogleFonts.gochiHand(
fontSize: 70.0,
color: Colors.white,
),
),
GestureDetector(
onTap: login,
child: Container(
height: 60.0,
width: 260.0,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/google_signin_button.png'),
fit: BoxFit.cover,
)
),
),
),
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
return isAuth ? buildAuthScreen() : buildUnauthScreen();
}
}
You have created an optional named parameter currentUser in your StatefulWidget Upload. I think the user that you have passed in the Upload widget is null.
You have to check where are you calling the Upload widget from & then check whether the user is null or not.
However, if the currentUser is null, you can prevent the error by using null aware operator as follows:
leading: CircleAvatar(
backgroundImage: CachedNetworkImageProvider(
widget.currentUser?.photoUrl, // <-----
),
),
Your current user is null. You have to set a user in here:
final User currentUser;