Flutter Chat Screen Textinputfield - database

I have create a Chat in my app. My problem is that when someone want to type in the Inputfield the Inputfield goes up because of the phone keyboard but my chat dont show the last message above the Inputfield. Does anyone know how to fix this? Chatscreen and Chatscreen with keyboard
class Chat extends StatefulWidget {
final String chatRoomId;
Chat({this.chatRoomId});
#override
_ChatState createState() => _ChatState();
}
class _ChatState extends State<Chat> {
Stream<QuerySnapshot> chats;
TextEditingController messageEditingController = new TextEditingController();
Stream chatRooms;
Widget chatMessages(){
return StreamBuilder(
stream: chats,
builder: (context, snapshot){
return snapshot.hasData ?
ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index){
return MessageTile(
message: snapshot.data.docs[index].data()["message"],
sendByMe: Constants.myName == snapshot.data.docs[index].data()["sendBy"],
time: snapshot.data.docs[index].data()["time"],
);
},
) : SpinKitFadingCircle(color: Colors.white, size: 20.0);
},
);
}
addMessage() {
if (messageEditingController.text.isNotEmpty) {
Map<String, dynamic> chatMessageMap = {
"sendBy": Constants.myName,
"message": messageEditingController.text,
'time': DateTime
.now()
.millisecondsSinceEpoch,
};
DatabaseService().addMessage(widget.chatRoomId, chatMessageMap);
setState(() {
messageEditingController.text = "";
});
}
}
#override
void initState() {
DatabaseService().getChats(widget.chatRoomId).then((val) {
setState(() {
chats = val;
});
});
super.initState();
}
Future<DocumentSnapshot> getUserInfo() async {
var firebaseUser = await FirebaseAuth.instance.currentUser;
return await FirebaseFirestore.instance.collection("SerX")
.doc(firebaseUser.uid)
.get();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.black,
bottom: PreferredSize(
child: Container(
color: Colors.blue,
height: 4.0,
),
preferredSize: Size.fromHeight(0)),
title:Text("Conversation",
style: TextStyle(
color: Colors.white,
fontFamily: 'Orbitron',
fontSize: 20.0,
fontWeight: FontWeight.bold,
letterSpacing: 2.2
),),
leading: IconButton(icon: Icon(Icons.arrow_back ,color: Colors.blue,),onPressed: (){
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => Search()));
},),
),
body: Container(
child: Stack(
children: [
Container(child: chatMessages(), height: 595),
Container(
alignment: Alignment.bottomCenter,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 25, vertical: 3),
color: Colors.white,
child: Row(
children: [
Expanded(
child: TextField(
controller: messageEditingController,
style: TextStyle(
color: Colors.white,
fontFamily: 'Orbitron',
fontSize: 12.0,
fontWeight: FontWeight.bold,
),
decoration: InputDecoration(
contentPadding: new EdgeInsets.symmetric(vertical: 7, horizontal: 15),
filled: true,
fillColor: Colors.black,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(40),
borderSide: BorderSide(color: Colors.blue, width: 3)
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(40),
borderSide: BorderSide(color: Colors.blue, width: 3,)
),
border: InputBorder.none,
),
),
),
SizedBox(width: 20,),
GestureDetector(
onTap: () {
addMessage();
},
/*
child:Container(
height: 45,
width: 45,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
const Color(0xFF000000),
const Color(0xFF000000),
]
),
borderRadius: BorderRadius.circular(40),
border: Border.all(
width: 2,
color: Colors.blue
)
),
*/
child:Icon(Icons.send, color: Colors /// <--- Um den grauen script zu aktivieren hinter Icon eine klammer zu setzen!
.black, size: 35,),
),
],
),
),
),
],
),
),
);
}
}
class MessageTile extends StatelessWidget {
final String message;
final bool sendByMe;
final int time;
MessageTile({#required this.message, #required this.sendByMe, #required this.time});
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(
top: 3,
bottom: 3,
left: sendByMe ? 0 : 24,
right: sendByMe ? 24 : 0),
alignment: sendByMe ? Alignment.centerRight : Alignment.centerLeft,
child: Container(
margin: sendByMe
? EdgeInsets.only(left: 30)
: EdgeInsets.only(right: 30),
padding: EdgeInsets.only(
top: 17, bottom: 17, left: 20, right: 20),
decoration: BoxDecoration(
borderRadius: sendByMe ? BorderRadius.only(
topLeft: Radius.circular(9),
topRight: Radius.circular(9),
bottomLeft: Radius.circular(9),
) :
BorderRadius.only(
topLeft: Radius.circular(9),
topRight: Radius.circular(9),
bottomRight: Radius.circular(9)),
color: sendByMe ? Colors.blue : Colors.white
),
child: Text(message,
textAlign: TextAlign.start,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontFamily: 'Orbitron',
fontSize: 9.0,),),
),
);
}
}

The cause of the error is that you set 595 pixels as a fixed height for the Container your chatMessages widget is in.
Container(child: chatMessages(), height: 595),
An easy solution would be to calculate the height of the keyboard (see this question):
Container(child: chatMessages(), height: MediaQuery.of(context).size.height - 134 - MediaQuery.of(context).viewInsets.bottom),
This takes the actual height of your device and subtracts the height of appBar, textinputfield and keyboard.
However, it would be more efficient to use a widget tree that does not depend on pixel calculations. Especially the part with the keyboard may lead to lagging on slower devices.

Related

i can't display my data from the database

so this is the create quiz interface where the teacher can insert the title of the quiz , the question and the option
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mr_quiz/DB_helper.dart';
import 'package:random_string/random_string.dart';
import 'DB_helper.dart';
import 'question.dart';
import 'qcm.dart';
import 'choix.dart';
import 'folder.dart';
class Create_Quiz extends StatefulWidget {
#override
_Create_QuizState createState() => _Create_QuizState();
}
class _Create_QuizState extends State<Create_Quiz> {
bool choix = false;
late String question;
late String option;
late String titre;
String qst_id=randomAlphaNumeric(16);
String op_id=randomAlphaNumeric(16);
String qcm_id=randomAlphaNumeric(16);
TextEditingController titre_ctrl=TextEditingController();
TextEditingController qst_ctrl=TextEditingController();
TextEditingController choix_ctrl=TextEditingController();
add_qst(Question question){
DB_helper.instance.insertquestion(question);
print('question ajoutée');
}
add_qcm(Qcm qcm){
DB_helper.instance.insertqcm(qcm);
print('qcm ajouté');
}
add_choix(Choix choix){
DB_helper.instance.insertchoix(choix);
print('choix ajouté');
}
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
fontFamily: 'HindGuntur',
),
debugShowCheckedModeBanner: false,
title: 'Mr.Quiz',
routes: {
'/folder': (BuildContext context) => Folder()},
home: Builder(builder: (context) => Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomInset: false,
appBar: AppBar(
backgroundColor: Colors.white,
title: Text('QCM', style: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold),),
centerTitle: true,
elevation: 0.0,
leading: IconButton(icon: Icon(Icons.arrow_back),
onPressed: () {},
color: Colors.deepPurple,),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Center(child: Container(
height: 160.0,
width: 650.0,
margin: EdgeInsets.fromLTRB(30, 15, 30, 15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
color: Colors.deepPurple.shade50,),
child: Column(
children: <Widget>[
SizedBox(height: 15.0,),
Text("Entrez le titre du QCM:",
style: TextStyle(fontWeight: FontWeight.bold,),
),
Container(
width: 300.0,
child: TextFormField(
controller: titre_ctrl,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding: EdgeInsets.fromLTRB(20, 10, 5,
10),
hintText: 'Titre',
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.deepPurple,),
borderRadius: BorderRadius.circular(30.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.deepPurple.shade200,),
borderRadius: BorderRadius.circular(30.0),
),
),
),
),
],
),
),
),
SizedBox(height: 20.0,),
Container(
width: 350.0,
child: TextFormField(
controller: qst_ctrl,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(10, 10, 10, 10),
hintText: 'Question ',
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.deepPurple.shade100,),
borderRadius: BorderRadius.circular(30.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.deepPurple.shade200,),
borderRadius: BorderRadius.circular(30.0),
),
),
),
),
SizedBox(height: 20.0,),
Row(
children: [
Expanded(
flex: 6,
child: TextFormField(
controller: choix_ctrl,
decoration: InputDecoration(
hintText: "option ",
contentPadding: EdgeInsets.fromLTRB(20, 10, 10, 10),
),
),
),
Flexible(
child: SizedBox(
width: 5,
child: Checkbox(value: choix,
onChanged: (val) {
setState(() {
choix= val!;
});
},
activeColor: Colors.deepPurple,
checkColor: Colors.white,
),
),
)
],
),
Row(
children: <Widget>[
SizedBox(width: 120.0),
Icon(Icons.add_circle_outline, color: Colors.deepPurple,
size: 22.0,),
TextButton(
child: Text(
'ajouter un choix', textAlign: TextAlign.center,
style: TextStyle(
color: Colors.deepPurple, fontSize: 16.0),),
onPressed: () {setState(() {
option=choix_ctrl.text;
});
Choix choice =new Choix(op_id,option,choix);
add_choix(choice);
choix_ctrl.clear();},
),
],
),
SizedBox(height: 30.0,),
Column(
children: <Widget>[
ElevatedButton(style: ElevatedButton.styleFrom(
primary: Colors.deepPurple.shade200,
fixedSize: Size(300.0, 50.0),
elevation: 0.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
),
child:
Text('Ajouter Question',
style: TextStyle(fontSize: 16.0),),
onPressed: () {setState(() {
question=qst_ctrl.text;
});
Question qst =new Question(qst_id,question);
add_qst(qst);
qst_ctrl.clear();},),
SizedBox(height: 20.0,),
ElevatedButton(style: ElevatedButton.styleFrom(
primary: Colors.indigo.shade400,
fixedSize: Size(250.0, 50.0),
elevation: 0.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
),
child:
Text(
'valider mon QCM', style: TextStyle(fontSize: 16.0),),
onPressed: () {setState(() {
titre=titre_ctrl.text;
});
Qcm qcm =new Qcm(qcm_id,titre);
add_qcm(qcm);
Navigator.pushNamed(context, '/folder');
},),
],
),
SizedBox(height: 10.0,),
],),
),
),
)
);
}`
this is the folder interface where the quiz title is displayed
import 'package:flutter/material.dart';
import 'DB_helper.dart';
import'package:mr_quiz/createquiz.dart';
import 'qcm.dart';
import 'package:mr_quiz/question.dart';
import 'package:mr_quiz/choix.dart';
class Folder extends StatefulWidget {
const Folder({Key? key}) : super(key: key);
#override
_FolderState createState() => _FolderState();
}
class _FolderState extends State<Folder> {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
fontFamily: 'HindGuntur',
),
debugShowCheckedModeBanner: false,
title: 'Mes QCM',
home: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.white,
appBar: AppBar(backgroundColor: Colors.deepPurple.shade200,
elevation: 0.0,
centerTitle: true,
title: Text(
"Mes QCM",
style:
TextStyle(
color: Colors.white,
fontWeight: FontWeight.w500,
),
),
),
body:FutureBuilder<List<Qcm>>(
future : DB_helper.instance.qcms(),
builder: (BuildContext context, AsyncSnapshot<List<Qcm>> snapshot) {
if (snapshot.hasData) {
List<Qcm>? qcms = snapshot.data;
return ListView.builder(
itemCount: qcms?.length,
itemBuilder: (context, index){
final qcm = qcms![index];
return Dismissible(key: Key(qcm.qcm_id),
onDismissed: (direction){
setState(() {
DB_helper.instance.deleteprofil(qcm.qcm_id);
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("${qcm.titre} supprimé")));
},
background: Container(color: Colors.red),
child: ProfWidget(qcm: qcm, ));
},
);
} else {
return Center(child: CircularProgressIndicator());
}
}
),
)
);
}
}
class ProfWidget extends StatelessWidget {
const ProfWidget({Key? key, required this.qcm}) : super(key: key);
final Qcm qcm;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){
},
child: Card(
margin: EdgeInsets.all(8),
elevation: 8,
child: Row(
children: [
Padding(
padding: EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.only(bottom: 8),
child: Text(qcm.titre,
style:
TextStyle(fontWeight: FontWeight.bold, fontSize: 20)),
),
],
),
)
],
),
),
);
}
}
only the loading indicator is showing could anyone please help me solve this problem , and also can anyone please tell me how to display the data in the playquiz interface , we have a table for each model and they're related to each other with foreign keys but i don't know how to display data from them like i want to display the questions that belong to the same quiz and the options for each question

How to get multiple urls from firebase storage as array in firestore document?

I have an form (writeUrltoFirestore) which is working except for an array of urls which has to be taken from storage and added to firestore document.
Currently for every file url added in form I have new document at firestore.
So if I select 5 documents and click on "Create" button it will create 5 exactly same documents with only difference their "url" in (writeUrltoFirestore).
As I mentioned it has to create single document in firestore with array of urls for each file stored in storage.
BTW Iam not a programmer - didn't read any book, just always wanted to learn how to make an working app (kinda a dream) so please explain like to a moron if you can and don't get mad if you see something stupid.
Thanks to anyone which is willing to help me.
I need result like this link
Here is code below with some explanations.
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:file_picker/file_picker.dart';
import 'dart:io' show File;
class Fields extends StatefulWidget {
const Fields({Key? key}) : super(key: key);
#override
_FieldsState createState() =>
_FieldsState();
}
class _FieldsState extends State<Fields> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(child: _Body111()),
);
}
}
class _Body111 extends StatefulWidget {
#override
__Body111State createState() => __Body111State();
}
class __Body111State extends State<_Body111> {
final FirebaseStorage _firebaseStorage = FirebaseStorage.instance;
List<UploadTask> uploadedTasks = [];
List<File> selectedFiles = [];
//-----------------------------------------------------------------------------
// Select files to be uploaded to Storage
Future selectFileTo() async {
try {
FilePickerResult? result = await FilePicker.platform
.pickFiles(allowMultiple: true, type: FileType.any);
if (result != null) {
selectedFiles.clear();
for (var selectedFile in result.files) {
File file = File(selectedFile.path ?? '');
selectedFiles.add(file);
}
} else {
print("User has cancelled the selection");
}
} catch (e) {
print(e);
}
}
//---------------------------------------------------------------------------
// Upload selected files to Storage
uploadFileToStorage(File file) {
UploadTask task = _firebaseStorage
.ref()
.child("files/${DateTime.now().toString()}")
.putFile(file);
return task;
}
//----------------------------------------------------------------------------
// Save files to Storage and get files Urls
saveImageUrlToFirebase(UploadTask task) {
task.snapshotEvents.listen((snapShot) {
if (snapShot.state == TaskState.success) {
snapShot.ref.getDownloadURL().then((urls) =>
writeUrltoFirestore(urls));
}
});
}
//--------------------------------------------------------------------------
// Save files Urls to Firestore document
writeUrltoFirestore(urls) {
Map<String, dynamic> firestoredocData = {
"issue type": selectedValue,
"description": descriptionController.text,
"location": 'Building A',
"category": selectedCategory,
"subcategory": selectedSubcategory,
"uid": firebaseUser!.uid,
//----------------------------------------------------------------------
//----------------------------------------------------------------------
"url": urls, // HERE I HAVE TO STORE ARRAY OF URLS FROM STORAGE
//----------------------------------------------------------------------
//----------------------------------------------------------------------
};
CollectionReference collectionReference =
FirebaseFirestore.instance.collection('issues');
collectionReference.add(firestoredocData);
}
//--------------------------------------------------------------------------
// Button that triggers all
addData() async {
for (var file in selectedFiles) {
final UploadTask task = uploadFileToStorage(file);
saveImageUrlToFirebase(task);
setState(() {
uploadedTasks.add(task);
});
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('created successfully')));
Navigator.pop(context);
}
//----------------------------------------------------------------------------
// Other fields from Map above
List<String> categories = ['111', '222', '333'];
List<String> generalSubcategory = ['1111111', '2222222', '333333333'];
List<String> cleaningSubcategory = [
'1',
'2',
'3'
];
List<String> othersSubcategory = ['01', '02', '03'];
List<String> subcategory = [];
String? selectedCategory;
String? selectedSubcategory;
final TextEditingController descriptionController = TextEditingController();
var firebaseUser = FirebaseAuth.instance.currentUser;
String? selectedValue;
List<String> arrayList = [
'Individual ',
'Maintenance '
];
Widget _description() {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 35, 0, 0),
child: TextFormField(
controller: descriptionController,
decoration: InputDecoration(
hintText: 'Here you can describe ...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
borderSide: const BorderSide(color: Colors.grey),
),
),
maxLines: 8,
),
);
}
#override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) =>
Stack(
children: [
GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: SingleChildScrollView(
child: Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0),
child: _description(),
),
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0),
child: Container(
padding: const EdgeInsets.fromLTRB(13, 0, 25, 0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: const [
BoxShadow(
color: Colors.grey,
spreadRadius: 2,
blurRadius: 2,
offset:
Offset(5, 5), // changes position of shadow
),
],
border: Border.all(
color: Colors.grey, width: 1.0),
borderRadius:
const BorderRadius.all(Radius.circular(20)),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
dropdownColor: Colors.white,
borderRadius: BorderRadius.circular(20),
hint: const Padding(
padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Text(
'Categories',
style: TextStyle(),
)),
value: selectedCategory,
isExpanded: true,
items: categories.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Padding(
padding:
const EdgeInsets.fromLTRB(25, 0, 0, 0),
child: Text(
value,
textAlign: TextAlign.center,
style: const TextStyle(),
),
),
);
}).toList(),
onChanged: (category) {
if (category == '222') {
subcategory = cleaningSubcategory;
} else if (category == '111') {
subcategory = generalSubcategory;
} else if (category == '333') {
subcategory = othersSubcategory;
} else {
subcategory = [];
}
setState(() {
selectedSubcategory = null;
selectedCategory = category;
});
},
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0),
child: Container(
padding: const EdgeInsets.fromLTRB(20, 0, 25, 0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: const [
BoxShadow(
color: Colors.grey,
spreadRadius: 2,
blurRadius: 2,
offset:
Offset(5, 5), // changes position of shadow
),
],
border: Border.all(
color: Colors.grey, width: 1.0),
borderRadius:
const BorderRadius.all(Radius.circular(20)),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
dropdownColor: Colors.white,
borderRadius: BorderRadius.circular(20),
hint: const Padding(
padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Text(
'Subcategories',
style: TextStyle(),
)),
value: selectedSubcategory,
isExpanded: true,
items: subcategory.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Padding(
padding:
const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Text(value),
),
);
}).toList(),
onChanged: (subcategory) {
setState(() {
selectedSubcategory = subcategory;
});
},
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0),
child: Container(
padding: const EdgeInsets.fromLTRB(20, 0, 25, 0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: const [
BoxShadow(
color: Colors.grey,
spreadRadius: 2,
blurRadius: 2,
offset:
Offset(5, 5), // changes position of shadow
),
],
border: Border.all(
color: Colors.grey, width: 1.0),
borderRadius:
const BorderRadius.all(Radius.circular(20)),
),
child: DropdownButtonHideUnderline(
child: DropdownButtonFormField<String>(
dropdownColor: Colors.white,
decoration: const InputDecoration(
enabledBorder: InputBorder.none,
),
validator: (value) =>
selectedValue == null
? 'Please select type'
: null,
hint: const Padding(
padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Text(
'Type',
),
),
value: selectedValue,
isExpanded: true,
icon: const Icon(Icons.arrow_drop_down),
items: arrayList.map((String string) {
return DropdownMenuItem<String>(
value: string,
child: Padding(
padding:
const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Text(string),
),
);
}).toList(),
onChanged: (String? string) {
setState(() {
selectedValue = string;
});
},
),
),
),
),
const Padding(
padding: EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0)),
IconButton(
onPressed: selectFileTo,
icon: const Icon(
Icons.camera_alt_outlined,
size: 30,
color: Colors.grey,
)),
const Padding(
padding: EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0)),
Padding(
padding: const EdgeInsets.only(
left: 30.0, right: 30.0, top: 5.0),
child: ElevatedButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(
const EdgeInsets.all(0)),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
)),
backgroundColor: MaterialStateProperty.all<
Color>(
Colors.transparent),
shadowColor: MaterialStateProperty.all<Color>(
Colors.transparent)),
onPressed: addData,
child: Container(
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(20)),
),
constraints: const BoxConstraints(
minWidth: 120, minHeight: 40),
alignment: Alignment.center,
child: const Center(
child: Text(
"Create",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
),
),
),
],
),
),
),
),
],
),
);
}
}
// End of dart file
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Firebase API (separate dart file)
import 'dart:io';
import 'dart:typed_data';
import 'package:firebase_storage/firebase_storage.dart';
class FirebaseApi {
static UploadTask? uploadFile(String destination, File file) {
try {
final ref = FirebaseStorage.instance.ref(destination);
return ref.putFile(file);
} on FirebaseException catch (e) {
return null;
}
}
static UploadTask? uploadBytes(String destination, Uint8List data) {
try {
final ref = FirebaseStorage.instance.ref(destination);
return ref.putData(data);
} on FirebaseException catch (e) {
return null;
}
}
}
//-----------------------------------------------------------------------------
You should call writeUrltoFirestore at last of all upload. Maintain an List at top.
List<String> _urls = [];
in saveImageUrlToFirebase
saveImageUrlToFirebase(UploadTask task) {
task.snapshotEvents.listen((snapShot) {
if (snapShot.state == TaskState.success) {
snapShot.ref.getDownloadURL().then((url) =>
_urls.add(url.toString()));
}
});
}
In final upload task simply call
writeUrltoFirestore(_urls);

Use while loop to repeat 3 widgets. in flutter

I want to repeat the following code with index values from 1 to n. How to do it in flutter ?
return ListView(
children: <Widget>[
SizedBox(
height: 15.0,
),
new Image.asset(
"assets/$name/$index.jpg",
fit: BoxFit.cover,
),
SizedBox(
height: 10.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("$name $index",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 23,
fontFamily: 'Raleway',
color: Colors.black)),
Container(
margin: EdgeInsets.only(left: 100.0),
width: 150.0,
height: 50.0,
child: FlatButton(
onPressed: null,
child: Text('Download',
style: TextStyle(color: Colors.black, fontSize: 20)),
textColor: Colors.white,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.teal, width: 2, style: BorderStyle.solid),
borderRadius: BorderRadius.circular(50)),
),
),
],
),
],
);
To show 3 times simple text using while loop.
Widget getWidgets() {
List<Widget> list = new List<Widget>();
int i = 0;
while (i < 3) {
list.add(new Text(strings[i]));
i++;
}
return Row(children:list);
}
You can copy paste run full code below
You can use ListView.builder with itemCount and wrap Column
code snippet
ListView.builder(
itemCount: 10,
itemBuilder: (BuildContext ctxt, int index) {
return Column(
children: <Widget>[
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView.builder(
itemCount: 10,
itemBuilder: (BuildContext ctxt, int index) {
return Column(
children: <Widget>[
SizedBox(
height: 15.0,
),
Image.network(
"https://picsum.photos/50?image=$index",
fit: BoxFit.cover,
),
SizedBox(
height: 10.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("$index",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 23,
fontFamily: 'Raleway',
color: Colors.black)),
Container(
margin: EdgeInsets.only(left: 100.0),
width: 150.0,
height: 50.0,
child: FlatButton(
onPressed: null,
child: Text('Download',
style:
TextStyle(color: Colors.black, fontSize: 20)),
textColor: Colors.white,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.teal,
width: 2,
style: BorderStyle.solid),
borderRadius: BorderRadius.circular(50)),
),
),
],
),
],
);
}),
);
}
}

Unable to create data tables dynamically using TextField input

I am trying out to create an invoice application, wherein the user is entering the data, and then it should come up listed as a table.
What I have achieved so far is just a single row with just a single user input detail like with errors in it as well...
I wanted the application to
HardCoded Code:
class Sixth extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return SixthState();
}
}
class SixthState extends State<Sixth> {
final pdf = pw.Document();
String path;
share() async {
Share.shareFiles([path]);
}
create() async {
print('creating');
pdf.addPage(pw.MultiPage(
pageFormat: PdfPageFormat.a4,
margin: pw.EdgeInsets.all(12),
build: (pw.Context context) {
return <pw.Widget>[
pw.Paragraph(
text: 'SOLUTION HUB\nVENDORS',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
pw.Paragraph(
padding: pw.EdgeInsets.only(left: 450),
text: 'Billing Address:',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
pw.Row(children: [
pw.Paragraph(
text: 'wrqijwqiojqwoirjq\nirjorwiuroeriuwor\noerweo8rw',
padding: pw.EdgeInsets.only(top: 10)),
pw.SizedBox(width: 370),
pw.Paragraph(
text: 'wrqijwqiojqwoirjq\nirjorwiuroeriuwor\noerweo8rw',
padding: pw.EdgeInsets.only(top: 10))
]),
pw.Paragraph(
padding: pw.EdgeInsets.only(top: 15),
text: 'PAN No. ${panvalue}',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
pw.Paragraph(
padding: pw.EdgeInsets.only(top: 15),
text: 'GST Registration No. ${gstvalue}',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
pw.Paragraph(
padding: pw.EdgeInsets.only(top: 15),
text: 'Order No. ${ordernovalue}',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
pw.Paragraph(
padding: pw.EdgeInsets.only(top: 15),
text: 'Order Date. ${orderdatevalue}',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
pw.Paragraph(
padding: pw.EdgeInsets.only(left: 450),
text: 'INVOICE NUMBER\n03950234982042980',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
pw.SizedBox(height: 20),
pw.Table.fromTextArray(data: <List<String>>[
<String>[
'SI\nNo.',
'Description',
'Unit\nPrice',
'Qty',
'Net Amount',
'Tax\nRate',
'Tax\nType',
'Tax\nAmt',
'Total\nAmt'
],
<String>[
'1',
'${SecondState.descriptionController.text}',
'${ThirdState.unitpriceController.text}',
'1',
'500',
'${FourthState.taxrateController.text}',
'${FourthState.taxtypeController.text}',
'${FourthState.taxamountController.text}',
'276.6'
],
])
];
},
));
}
Future save() async {
print('sacing');
Directory directory = await getApplicationDocumentsDirectory();
String documentpath = directory.path;
File file = File("$documentpath/example.pdf");
setState(() {
path = "$documentpath/example.pdf";
});
file.writeAsBytesSync(pdf.save());
}
int _value = 1;
AnimationController animationController;
Animation<Offset> offset;
static var panvalue;
static var gstvalue;
static var ordernovalue;
static var orderdatevalue;
static var descriptionvalue;
static var unitpricevalue;
static var quantityvalue;
static var taxratevalue;
static var taxtypevalue;
static var taxamtvalue;
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
drawer: Drawer(),
appBar: AppBar(
centerTitle: true,
title: Text('ORDER DETAILS'),
backgroundColor: Colors.blueGrey,
actions: <Widget>[
Padding(
padding: EdgeInsets.all(2),
child: IconButton(
onPressed: () {}, //USER PROFILE
icon: Icon(Icons.supervised_user_circle),
iconSize: 30,
),
)
],
),
body: SingleChildScrollView(
child: SafeArea(
child: Column(children: <Widget>[
Container(
padding: EdgeInsets.only(right: 220, top: 20),
child: Text(
'SOLUTION HUB \n VENDORS',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
),
Container(
padding: EdgeInsets.only(left: 240),
child: Text(
'Billing Adress:',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
),
SizedBox(
height: 15,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 30),
child:
Text('Ubga wjpw wiqjoiw\n owqkdw qwok qoqkw \nojq vpoqk'),
),
Container(
padding: EdgeInsets.only(right: 15),
child: Text('oefkwpfoke 20-32 \n 032902 0239 \n 0392230'),
)
],
),
Container(
width: 800,
padding: EdgeInsets.only(left: 35, right: 10, top: 45),
child: Text(
"Pan No. ${panvalue}",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Container(
width: 800,
padding: EdgeInsets.only(left: 35, right: 10, top: 25),
child: Text(
"GST REGISTRATION NO. ${gstvalue}",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Container(
width: 800,
padding: EdgeInsets.only(left: 35, right: 10, top: 25),
child: Text(
"Order No. ${ordernovalue} ",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Container(
width: 400,
padding: EdgeInsets.only(left: 35, right: 20, top: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Order Date: ${orderdatevalue}",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(
'INVOICE NUMBER',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
)
],
),
),
Container(
padding: EdgeInsets.only(left: 250, top: 5),
child: Text('5920384283429')),
Row(
children: <Widget>[
Expanded(
child: SingleChildScrollView(
child: DataTable(columnSpacing: 4, columns: [
DataColumn(
label: Text(
'Si\nNo.',
textAlign: TextAlign.left,
)),
DataColumn(label: Text('Description')),
DataColumn(label: Text('Unit\nPrice')),
DataColumn(label: Text('Qty')),
DataColumn(label: Text('Net\namount')),
DataColumn(label: Text('Tax\nRate')),
DataColumn(label: Text('Tax\nType')),
DataColumn(label: Text('Tax\nAmt')),
DataColumn(label: Text('Total\nAmt'))
], rows: [
DataRow(cells: [
DataCell(Wrap(
children: <Widget>[
Text(
'1',
textAlign: TextAlign.start,
)
],
)),
DataCell(Text(
'${SecondState.descriptionController.text}',
textAlign: TextAlign.center,
)),
DataCell(Wrap(
children: <Widget>[
Text(
'${ThirdState.unitpriceController.text}',
textAlign: TextAlign.center,
)
],
)),
DataCell(Text('${ThirdState.quantityController.text}')),
DataCell(Text('500')),
DataCell(Text('${FourthState.taxrateController.text}')),
DataCell(Text('${FourthState.taxtypeController.text}')),
DataCell(Text('${FourthState.taxamountController.text}')),
DataCell(Text('500')),
])
]))),
],
),
SizedBox(
height: 150,
),
ButtonTheme(
minWidth: 110,
height: 50,
child: RaisedButton(
color: Colors.blue[300],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18)),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("COMPLETE ACTION USING"),
content: Container(
height: 150,
width: 100,
child: Column(
children: <Widget>[
FlatButton(
onPressed: () async {
create();
await save();
share();
},
child: Text('WhatsApp'),
),
FlatButton(
onPressed: () {},
child: Text('Gmail'),
),
FlatButton(
onPressed: () {},
child: Text("Download"),
)
],
),
),
);
});
},
child: Text('Share'),
),
)
]),
),
),
));
}
}
What I want to achieve is this
It should automatically add rows as user inputs enter details
Errors I have encountered:
Whenever I going to add more items the previous data are stored in the text fields.
There are more colors on the right side but am unable to view it.
Please help me solve this issue

First Flutter Application and i got stuck with an error

i was trying to pickup image from gallery and update it to UI. But on performing this it shows an error in profile.dart file at line 56.
The error occurs at _image.
The argument type 'File(where File is defined in
D:\Softwares\flutter\bin\cache\pkg\sky_engine\lib\html\html_dart2js.dart)'
can't be assigned to the parameter type 'File(where File is defined in
D:\Softwares\flutter\bin\caches\pkg\sky_engine\lib\io\file.dart)'
the complete code.
Main.dart
import 'package:flutter/material.dart';
import 'package:udharibook/Screens/SplashScreen.dart';
import 'package:udharibook/Screens/UserProfile.dart';
void main(){
runApp(
MaterialApp(
title: 'Udhari Book',
home:UserProfile(),
debugShowCheckedModeBanner: false,
theme: ThemeData(
backgroundColor: Color.fromRGBO(242, 242, 242, 1.0)
),
)
);
}
ProfilePage
import 'dart:html';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:image_picker/image_picker.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:path/path.dart';
class UserProfile extends StatefulWidget {
#override
_UserProfileState createState() => _UserProfileState();
}
class _UserProfileState extends State<UserProfile> {
File _image;
TextEditingController nameController =TextEditingController()..text='Mehul Jain';
TextEditingController mobileController =TextEditingController()..text='8856061841';
TextEditingController emailController =TextEditingController()..text='mehuljain3698#gmail.com';
TextEditingController addressController =TextEditingController()..text='Maharashtra';
#override
Widget build(BuildContext context) {
Future getImage() async{
var image=await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image=image as File;
print('Image Path $_image');
});
}
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text('User Profile'),
backgroundColor: Color.fromRGBO(162, 42, 43, 1.0),
),
body: Builder(
builder: (context) => Container(
child: Column(
children: <Widget>[
SizedBox(
height: 20.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Align(
alignment: Alignment.center,
child: CircleAvatar(
radius: 50,
backgroundColor: Color.fromRGBO(162, 42, 43, 1.0),
child: ClipOval(
child: SizedBox(
height: 180.0,
width: 180.0,
child:_image!=null?
Image.file(_image,fit: BoxFit.fill):
Image.network(
'https://randomwordgenerator.com/img/picture-generator/55e4d5464f5ba914f1dc8460962e33791c3ad6e04e5074417d2d73dc934bcd_640.jpg',
fit: BoxFit.fill,
)),
),
),
),
Padding(
padding: EdgeInsets.only(top: 60.0),
child: IconButton(
icon: Icon(Icons.camera_alt), onPressed: () {
getImage();
}),
)
],
),
Padding(
padding: EdgeInsets.only(top:20.0,left: 10.0,right: 10.0),
child:SizedBox(
height: 40.0,
child: TextField(
controller: nameController,
decoration: InputDecoration(
labelText: 'Full Name',
labelStyle:
TextStyle(fontFamily: 'Exo2', color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
color:
Color.fromRGBO(162, 42, 43, 1.0)
)
)
),
),
)),
Padding(
padding: EdgeInsets.only(top:15.0,left: 10.0,right: 10.0),
child:SizedBox(
height: 40.0,
child: TextField(
controller: mobileController,
enabled: false,
keyboardType:TextInputType.phone,
decoration: InputDecoration(
labelText: 'Mobile Number',
labelStyle:
TextStyle(fontFamily: 'Exo2', color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
color:
Color.fromRGBO(162, 42, 43, 1.0)
)
)
),
),
)),
Padding(
padding: EdgeInsets.only(top:15.0,left: 10.0,right: 10.0),
child:SizedBox(
height: 40.0,
child: TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email (Optional)',
labelStyle:
TextStyle(fontFamily: 'Exo2', color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
color:
Color.fromRGBO(162, 42, 43, 1.0)
)
)
),
),
)),
Padding(
padding: EdgeInsets.only(top:15.0,left: 10.0,right: 10.0,bottom: 30.0),
child: TextField(
maxLines: 3,
maxLengthEnforced: true,
controller: addressController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Address (Optional)',
labelStyle:
TextStyle(fontFamily: 'Exo2', color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
color:
Color.fromRGBO(162, 42, 43, 1.0)
)
)
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
SizedBox(
width:130.0,
height: 50.0,
child:RaisedButton(
color: Color.fromRGBO(162, 42, 43, 1.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0)
),
onPressed: (){
Navigator.of(context).pop();
},
elevation: 4.0,
splashColor: Colors.blueGrey,
child: Text(
'Save',
style: TextStyle(
color:Colors.white,fontSize: 22.0,fontFamily: 'Exo2'
),
),
)),
SizedBox(
width:130.0,
height:50.0,
child:RaisedButton(
color: Color.fromRGBO(162, 42, 43, 1.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0)
),
onPressed: (){
Navigator.of(context).pop();
},
elevation: 4.0,
splashColor: Colors.blueGrey,
child: Text(
'Cancel',
style: TextStyle(
color:Colors.white,fontSize: 22.0,fontFamily: 'Exo2'
),
),
))
],
)
],
),
),
),
);
}
}
Welcome To Flutter. I am sorry that you are experiencing this error! Trust me, Flutter is really User friendly so soon you will get the hang of it :)
So it appears that this error is appearing due to a conflict within 2 or more imports that use File. Look at this thread: File cant be assigned with ImagePicker Flutter

Resources