this is what happening
when i try to get list without filtering it's working good. but when i try to filter list using where condition is not working
this is what happening
when i try to get list without filtering it's working good. but when i try to filter list using where condition is not working
this is what happening
when i try to get list without filtering it's working good. but when i try to filter list using where condition is not working
late String _email = '';
var _users = [];
String api =
'https://raw.githubusercontent.com/ilkacase1234/Amore/main/Users.json';
login() async {
try {
final response = await http.get(Uri.parse(api));
var data = json.decode(response.body) as List;
setState(() {
_users = data;
});
} catch (e) {
EasyLoading.showError(e.toString());
}
}
#override
void initState() {
login();
super.initState();
}
check() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final String? login = prefs.getString('login');
if (login != null) {
Navigator.pushReplacementNamed(context, HomePage.id);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Login'),
elevation: 0,
bottom: PreferredSize(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Column(
children: [
TextField(
onChanged: (val) {
setState(() {
_email = val;
});
},
keyboardType: TextInputType.url,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5)),
fillColor: Colors.white,
contentPadding: EdgeInsets.zero,
hintText: 'Halkan ku qor magalada gurigu ku yaalo',
prefixIcon: IconButton(
icon: Icon(Icons.menu),
onPressed: () {},
),
suffixIcon: IconButton(
icon: Icon(Icons.search),
onPressed: () {},
),
filled: true,
),
),
],
),
),
preferredSize: Size.fromHeight(56),
),
),
body: ListView.builder(
itemCount: _users.length,
itemBuilder: (context, index) {
final currentUser = _users[index];
if (_users.isEmpty) {
return Center(child: Text('No data'));
} else {
return Card(
child: ListTile(
leading: CircleAvatar(
radius: 28,
backgroundImage:
NetworkImage(currentUser['image'].toString()),
),
title: Text(currentUser['email'].toString()),
subtitle: Column(
children: [
Text(currentUser['password'].toString()),
Text(currentUser['name'].toString()),
],
),
),
);
}
}),
);
}
}
late String _email = '';
var _users = [];
String api =
'https://raw.githubusercontent.com/ilkacase1234/Amore/main/Users.json';
login() async {
try {
final response = await http.get(Uri.parse(api));
var data = json.decode(response.body) as List;
var data1 = data
.where((el) => el['email']
.toLowerCase()
.contains(_email.toLowerCase()))
.toList();
setState(() {
_users = data1;
});
} catch (e) {
EasyLoading.showError(e.toString());
}
}
#override
void initState() {
login();
super.initState();
}
check() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final String? login = prefs.getString('login');
if (login != null) {
Navigator.pushReplacementNamed(context, HomePage.id);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Login'),
elevation: 0,
bottom: PreferredSize(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Column(
children: [
TextField(
onChanged: (val) {
setState(() {
_email = val;
});
},
keyboardType: TextInputType.url,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5)),
fillColor: Colors.white,
contentPadding: EdgeInsets.zero,
hintText: 'Halkan ku qor magalada gurigu ku yaalo',
prefixIcon: IconButton(
icon: Icon(Icons.menu),
onPressed: () {},
),
suffixIcon: IconButton(
icon: Icon(Icons.search),
onPressed: () {},
),
filled: true,
),
),
],
),
),
preferredSize: Size.fromHeight(56),
),
),
body: ListView.builder(
itemCount: _users.length,
itemBuilder: (context, index) {
final currentUser = _users[index];
if (_users.isEmpty) {
return Center(child: Text('No data'));
} else {
return Card(
child: ListTile(
leading: CircleAvatar(
radius: 28,
backgroundImage:
NetworkImage(currentUser['image'].toString()),
),
title: Text(currentUser['email'].toString()),
subtitle: Column(
children: [
Text(currentUser['password'].toString()),
Text(currentUser['name'].toString()),
],
),
),
);
}
}),
);
}
}
Try this:
login() async {
try {
final response = await http.get(Uri.parse(api));
response.body.forEach(e){
if(e["email"].toLowerCase() == _email.toLowerCase()){
_user = json.decode(e)
}
}
} catch (e) {
EasyLoading.showError(e.toString());
}}
Related
I am building a app to practice my Flutter skills. The app is a quiz app. I am trying to make it possible for users to add questions. I have a variable which is a list called: questions. I also have another variable called: answers (which is also a list). So they are separated, however, I have a variable for questionIndex so to display the question and assign the correct answer i use the index to define which list item is relevant.
Now I have an issue.... I succeeded in trying to add the questiontext with a function in my statefulwidget, however, trying to add an answer to the answers list is not working. It gives me the error: "The expression doesn't evaluate to a function, so it can't be invoked."
How would you solve this? Would be really thankful for some input!
The file with a StatefulWidget (containing the functions to add questions and answers):
import 'questionText.dart';
import 'buttons.dart';
import 'end.dart';
import '../pages/add_questions.dart';
import '../model/question_class.dart';
import '../model/Answer_class.dart';
class QuizPage extends StatefulWidget {
#override
State<QuizPage> createState() => _QuizPageState();
}
class _QuizPageState extends State<QuizPage> {
int questionIndex = 0;
int points = 0;
List<Widget> scoreKeeper = [];
var _questions = [
{
'Victor loves computers',
},
'Victor is learning Flutter',
'Victor\'s favorite team is Manchester United',
'Victor\'s favorite team is Chelsea'
];
List<bool> answers = [
true,
true,
false,
true,
];
void _addIndex() {
setState(() {
questionIndex = questionIndex + 1;
});
}
late bool userAnswer;
void _setUserAnswerTrue() {
setState(() {
userAnswer = true;
});
}
void _setUserAnswerFalse() {
setState(() {
userAnswer = false;
});
}
void _checkIfCorrect() {
bool correctAnswer = answers[questionIndex];
setState(() {
correctAnswer == userAnswer ? points = points + 1 : points = points;
print(points);
});
setState(
() {
correctAnswer == userAnswer
? scoreKeeper.add(
Icon(
Icons.check,
color: Colors.green,
),
)
: scoreKeeper.add(
Icon(
Icons.close,
color: Colors.red,
),
);
},
);
}
void restartQuiz() {
setState(() {
questionIndex = 0;
scoreKeeper.clear();
});
}
void addNewQuestion(String txTitle) {
final newTx = Question(
title: txTitle,
);
setState(() {
_questions.add(newTx.toString());
});
}
void addNewBool(bool txAnswer) {
final newBool = Answer(
correctAnswer: txAnswer,
);
setState(() {
answers.add(newBool());
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.grey.shade900,
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
AddQuestions(addNewQuestion, addNewBool),
),
);
},
icon: Icon(Icons.add),
),
],
),
backgroundColor: Colors.grey.shade900,
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: questionIndex < _questions.length
? Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
QuestionText(_questions, questionIndex),
QuButtons(_setUserAnswerTrue, _setUserAnswerFalse,
_checkIfCorrect, _addIndex),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Row(
children: scoreKeeper,
),
),
],
)
: EndOfQuiz(scoreKeeper, restartQuiz),
)),
);
}
}
My file containting the text inputs:
import 'package:flutter/material.dart';
class AddQuestions extends StatelessWidget {
final titleController = TextEditingController();
final answerController = TextEditingController();
final Function addQu;
final Function addBoo;
AddQuestions(this.addQu, this.addBoo);
void submitInput() {
final enteredTitle = titleController.text;
final enteredBool = answerController.text.toLowerCase();
addQu(
enteredTitle,
);
addBoo(
enteredBool,
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.grey.shade900,
appBar: AppBar(
backgroundColor: Colors.grey.shade900,
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.all(20),
child: TextField(
controller: titleController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Question Text',
),
onSubmitted: (_) => submitInput(),
),
),
Padding(
padding: const EdgeInsets.all(20),
child: TextField(
controller: answerController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'True/False',
),
onSubmitted: (_) => submitInput(),
),
),
FlatButton(
onPressed: () {
submitInput;
},
child: Text('Add button'),
)
],
),
),
);
}
}
The answers list is a boolean array and you are adding the newBool() as a function which is the object of Answer class.
newBool() is a function not a boolean value. And list needs a boolean value to add.
I implemented a search list with consultation to firebase. Initially, all registered users appear on the screen and when I click on one of the users, the app shows another screen with all the data for that user. When you start typing in the search field, only users with respect to the text entered appear.
However, a problem arose: when filtering a customer, only it appears on the screen and when I click to open the customer's information, the app shows the information of the first user in the general list (without taking into account the filter).
I believe that this happens due to the index, which looks at the position of the document in the firebase.
How to fix this? Thank you!
body: Column(
children: <Widget>[
SizedBox(
height: 5,
),
TextField(
controller: _procurarpaciente,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: "Pesquisar paciente",prefixIcon: Icon(Icons.search)
),
onChanged: (val) {
setState(() {
nome = val;
});
},
),
Expanded(
child: StreamBuilder<QuerySnapshot>(
stream: (nome != "" && nome != null)
? Firestore.instance
.collection('pacientes')
.where("indexList", arrayContains: nome)
.snapshots()
: Firestore.instance.collection("pacientes").snapshots(),
builder: (context, snapshot) {
switch(snapshot.connectionState){
case ConnectionState.none:
case ConnectionState.waiting:
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.error_outline),
Text("Usuário não encontrado")
],
),
);
default:
// List<DocumentSnapshot> documentos =
// snapshot.data.documents;
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot data = snapshot.data.documents[index];
return ListTile(
title: Text(
data['nome'],
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 16,
),),
subtitle:Text(
"Quarto: ${data['quarto']}",
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 14,
),),
leading:CircleAvatar(
backgroundImage: NetworkImage(data['foto']),
),
onTap: ()=> {
//print(data.documentID),
_navegarParaPerfil(context, items[index]),
}
);
},
);
}
}
),
)
],
),
void _navegarParaPerfil(BuildContext context, Paciente paciente) async{
await Navigator.push(context,
MaterialPageRoute(builder: (context) => TelaPaciente(paciente)),
);
}
dsdsd
Step 1:
class Employee {
Employee(this.employeeID, this.employeeName, this.branch, this.designation, this.location,
this.salary,
{this.reference});
double employeeID;
String employeeName;
String designation;
String branch;
String location;
double salary;
DocumentReference reference;
factory Employee.fromSnapshot(DocumentSnapshot snapshot) {
Employee newEmployee = Employee.fromJson(snapshot.data());
newEmployee.reference = snapshot.reference;
return newEmployee;
}
factory Employee.fromJson(Map<String, dynamic> json) =>
_employeeFromJson(json);
Map<String, dynamic> toJson() => _employeeToJson(this);
#override
String toString() => 'employeeName ${employeeName}';
}
Step 2:
class EmployeeRepository {
List<Employee> employees = [];
final CollectionReference collection =
FirebaseFirestore.instance.collection('employees');
Stream<QuerySnapshot> getStream() {
return collection.snapshots();
}
Future<DocumentReference> add(Employee employee) {
var documentReference = collection.add(employee.toJson());
return documentReference;
}
update(Employee employee) async {
collection.doc(employee.reference.id).update(employee.toJson());
}
delete(Employee employee) async {
collection.doc(employee.reference.id).delete();
}
fromSnapShot(DocumentSnapshot snapshot) => Employee.fromSnapshot(snapshot);
Future<List<Employee>> buildData(
AsyncSnapshot snapshot, String filterKey) async {
List<Employee> list = [];
List<Employee> filteredList = [];
/// Based on the user snapShot, you can convert into the List and return to
/// the futurebuilder
await Future.forEach(snapshot.data.docs, (element) async {
list.add(Employee.fromSnapshot(element));
}).then((value) {
if (filterKey != null) {
filteredList = list
.where((element) =>
element.employeeID.toString() == filterKey ||
element.employeeName == filterKey ||
element.designation == filterKey ||
element.branch == filterKey ||
element.location == filterKey ||
element.salary.toString() == filterKey)
.toList();
}
});
if (filteredList.isEmpty) {
return Future<List<Employee>>.value(list);
} else {
return Future<List<Employee>>.value(filteredList);
}
}
}
Step 3:
EmployeeRepository employeeRepository = EmployeeRepository();
TextEditingController textEditingController = TextEditingController();
String filteredText = '';
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('ListView'),
),
body: StreamBuilder(
stream: employeeRepository.getStream(),
builder: (context, snapShot) {
if (snapShot.data == null ||
snapShot.connectionState == ConnectionState.waiting ||
snapShot.hasError ||
snapShot.data.docs.length == 0) {
return Container(
child: Center(child: CircularProgressIndicator()),
);
} else {
return StatefulBuilder(builder: (context, innerSetState) {
return FutureBuilder(
future: employeeRepository.buildData(
snapShot, filteredText),
builder: (context, futureSnapShot) {
if (!futureSnapShot.hasData) {
return Container(
child: Center(child: CircularProgressIndicator()),
);
} else {
return Column(
children: [
TextField(
controller: textEditingController,
decoration: InputDecoration(
icon: Icon(Icons.search),
hintText: 'Search here!'),
onSubmitted: (value) {
innerSetState(() {
filteredText = value;
});
},
onChanged: (value) {
innerSetState(() {
filteredText = value;
});
},
),
Container(
height: 400,
child: ListView.builder(
itemCount: futureSnapShot.data.length,
itemBuilder: (context, index) {
final Employee employee =
futureSnapShot.data[index];
return ListTile(
title: Text(employee.employeeName),
trailing:
Text('Salary${employee.salary}'),
subtitle: Text(employee.designation),
onTap: () {
print(employee.salary);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
EmployeeDetailsPage(
employee)));
},
);
},
),
),
],
);
}
});
});
}
},
)));
}
Step 4:
class EmployeeDetailsPage extends StatelessWidget {
final Employee employeeData;
const EmployeeDetailsPage(this.employeeData);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Employee Details'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(child: Text(employeeData.employeeName, style: TextStyle(fontSize: 30))),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(child: Text(employeeData.designation, style: TextStyle(fontSize: 20))),
),
Text('Salary ${employeeData.salary.toString()}'),
],
),
);
}
}
<blockquote class="imgur-embed-pub" lang="en" data-id="a/aqBaJ7N" data-context="false" ></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
Hey! Unfortunately it didn't work, look what keeps happening.
I think this is because of the index I send as a parameter, which does not understand that the values have been filtered:
onTap: ()=> {
//print(data.documentID),
_navegarParaPerfil(context, items[index]),
}
void _navegarParaPerfil(BuildContext context, Paciente paciente) async{
await Navigator.push(context,
MaterialPageRoute(builder: (context) => TelaPaciente(paciente)),
);
}
Ideally, it would be validated by documentID instead of this index, but I was unable to change it
)
I tried to program a Calendar App, where every user has his own events. I want to stream the events from Firestore but there is always the Error message "type 'QuerySnapshot' is not a subtype of type 'List'". Error message
I think the problem is in the StreamBuilder in the main file.
I would be incredibly happy if someone could show me how to solve this mistake.
Thanks to everyone in advance who tries to help me.
This is my main file:
class KalenderTable extends StatefulWidget {
#override
_KalenderTableState createState() => _KalenderTableState();
}
class _KalenderTableState extends State<KalenderTable> {
CalendarController _controller;
Map<DateTime, List<dynamic>> _events;
List<dynamic> _selectedEvents;
Stream events;
#override
void initState() {
getUserInfogetEvents();
super.initState();
_controller = CalendarController();
_events = {};
_selectedEvents = [];
}
Map<DateTime, List<dynamic>> _groupEvents(List<EventModel> allEvents) {
Map<DateTime, List<dynamic>> data = {};
allEvents.forEach((event) {
DateTime date = DateTime(
event.eventDate.year, event.eventDate.month, event.eventDate.day, 12);
if (data[date] == null) data[date] = [];
data[date].add(event);
});
return data;
}
getUserInfogetEvents() async {
Constants.myName = await HelperFunctions.getUserEmailSharedPreference();
DatabaseKalenderMethods().getUserEvents(Constants.myName).then((snapshots) {
setState(() {
events = snapshots;
print(
"we got the data + ${events.toString()} this is name ${Constants.myName}");
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: events,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<EventModel> allEvents = snapshot.data;
if (allEvents.isNotEmpty) {
_events = _groupEvents(allEvents);
} else {
_events = {};
_selectedEvents = [];
}
}
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TableCalendar(
events: _events,
initialCalendarFormat: CalendarFormat.twoWeeks,
calendarStyle: CalendarStyle(
canEventMarkersOverflow: true,
todayColor: Colors.orange,
selectedColor: Colors.cyan,
todayStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.white)),
headerStyle: HeaderStyle(
centerHeaderTitle: true,
formatButtonDecoration: BoxDecoration(
color: Colors.cyan,
borderRadius: BorderRadius.circular(20.0),
),
formatButtonTextStyle: TextStyle(color: Colors.white),
formatButtonShowsNext: false,
),
startingDayOfWeek: StartingDayOfWeek.monday,
onDaySelected: (date, events) {
setState(() {
_selectedEvents = events;
});
},
builders: CalendarBuilders(
selectedDayBuilder: (context, date, events) => Container(
margin: const EdgeInsets.all(4.0),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(10.0)),
child: Text(
date.day.toString(),
style: TextStyle(color: Colors.white),
)),
todayDayBuilder: (context, date, events) =>
Container(
margin: const EdgeInsets.all(4.0),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(10.0)),
child: Text(
date.day.toString(),
style: TextStyle(color: Colors.white),
)),
),
calendarController: _controller,
),
..._selectedEvents.map((event) => ContainerKalender(
event.title,
() {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => EventDetailsPage(
event: event,
)));
},
() {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => EventDetailsPage(
event: event,
)));
},
)),
],
),
);
}),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.cyan,
onPressed: () => Navigator.pushNamed(context, 'add_event'),
),
);
}
}
class EventModel extends DatabaseItem{
final String id;
final String title;
final String description;
final DateTime eventDate;
EventModel({this.id,this.title, this.description, this.eventDate}):super(id);
factory EventModel.fromMap(Map data) {
return EventModel(
title: data['title'],
description: data['description'],
eventDate: data['event_date'],
);
}
factory EventModel.fromDS(String id, Map<String,dynamic> data) {
return EventModel(
id: id,
title: data['title'],
description: data['description'],
eventDate: data['event_date'].toDate(),
);
}
Map<String,dynamic> toMap() {
return {
"title":title,
"description": description,
"event_date":eventDate,
"id":id,
};
}
}
This is my Firebase connection:
class DatabaseKalenderMethods {
getUserEvents(String itIsMyName) async {
return await Firestore.instance
.collection("kalender")
.where('users', arrayContains: itIsMyName)
.snapshots();
}
}
I'm guessing the issue is here :
List<EventModel> allEvents = snapshot.data;
This is because (still guessing) in events = snapshots;, the snapshots is a Stream<QuerySnapshot>.
See this answer to map the stream.
I have uploaded the Excel file to Realtime Database. I'm new and I find it very convenient. Especially if there is a need to unload data back for processing in an Excel file. So, it is difficult to find lessons on how to customize the search bar in the application. Please, help. I will also be glad if you can tell me where I can learn to work with databases for applications created in the Dart language.
class UserDashboard extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<UserDashboard> implements AddUserCallback {
TextEditingController editingController = TextEditingController();
bool _anchorToBottom = false;
FirebaseDatabaseUtil databaseUtil;
#override
void initState() {
super.initState();
databaseUtil = FirebaseDatabaseUtil();
databaseUtil.initState();
}
#override
void dispose() {
super.dispose();
databaseUtil.dispose();
}
#override
Widget build(BuildContext context) {
Widget _buildTitle(BuildContext context) {
return InkWell(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'List of students',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
),
);
}
List<Widget> _buildActions() {
return <Widget>[
new IconButton(
icon: const Icon(
Icons.group_add,
color: Colors.white,
),
onPressed: () => showEditWidget(null, false),
),
];
}
return new Scaffold(
appBar: AppBar(
title: _buildTitle(context),
actions: _buildActions(),
backgroundColor: Colors.deepPurple,
),
body: Container(
child: Column(children: <Widget>[
Expanded(
child: FirebaseAnimatedList(
key: ValueKey<bool>(_anchorToBottom),
query: databaseUtil.getUser(),
reverse: _anchorToBottom,
sort: _anchorToBottom
? (DataSnapshot a, DataSnapshot b) => b.key.compareTo(a.key)
: null,
itemBuilder: (BuildContext context, DataSnapshot snapshot,
Animation<double> animation, int index) {
return SizeTransition(
sizeFactor: animation,
child: showUser(snapshot),
);
},
),
),
]),
));
}
#override
void addUser(User user) {
setState(() {
databaseUtil.addUser(user);
});
}
#override
void update(User user) {
setState(() {
databaseUtil.updateUser(user);
});
}
Widget showUser(DataSnapshot res) {
User user = User.fromSnapshot(res);
var item = Card(
child: Container(
child: Center(
child: Row(
children: <Widget>[
CircleAvatar(
radius: 30.0,
child: Text(getShortName(user)),
backgroundColor: const Color(0xFF20283e),
),
Expanded(
child: Padding(
padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
user.name,
// set some style to text
style: TextStyle(
fontSize: 20.0, color: Colors.deepPurple),
),
Text(
user.club,
// set some style to text
style: TextStyle(
fontSize: 20.0, color: Colors.lightBlueAccent),
),
],
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: const Icon(
Icons.edit,
color: Colors.deepPurple,
),
onPressed: () => showEditWidget(user, true),
),
IconButton(
icon: const Icon(Icons.delete_forever),
color: Colors.deepPurple,
onPressed: () => onDelete(user),
),
],
),
],
),
),
padding: const EdgeInsets.fromLTRB(10.0, 0.0, 0.0, 0.0)),
);
return item;
}
String getShortName(User user) {
String shortName = "";
if (!user.name.isNotEmpty) {
shortName = user.name.substring(0, 1);
}
return shortName;
}
showEditWidget(User user, bool isEdit) {
showDialog(
context: context,
builder: (BuildContext context) =>
AddUserDialog().buildAboutDialog(context, this, isEdit, user),
);
}
void onDelete(User user) async {
if (await _showConfirmationDialog(context)) {
databaseUtil.deleteUser(user);
}
}
Future<bool> _showConfirmationDialog(BuildContext context) async {
return showDialog(
context: context,
barrierDismissible: true,
builder: (context) => AlertDialog(
content: Text("Delete?"),
actions: <Widget>[
FlatButton(
textColor: Colors.red,
child: Text("Delete"),
onPressed: () => Navigator.pop(context, true),
),
FlatButton(
textColor: Colors.black,
child: Text("Cancel"),
onPressed: () => Navigator.pop(context, false),
),
],
));
}
}
Here's how I load and unload data into the application:
class FirebaseDatabaseUtil {
DatabaseReference _counterRef;
DatabaseReference _userRef;
StreamSubscription<Event> _counterSubscription;
StreamSubscription<Event> _messagesSubscription;
FirebaseDatabase database = FirebaseDatabase();
int _counter;
DatabaseError error;
static final FirebaseDatabaseUtil _instance =
new FirebaseDatabaseUtil.internal();
FirebaseDatabaseUtil.internal();
factory FirebaseDatabaseUtil() {
return _instance;
}
void initState() {
// Demonstrates configuring to the database using a file
_counterRef = FirebaseDatabase.instance.reference().child('counter');
// Demonstrates configuring the database directly
_userRef = database.reference().child('record');
database.reference().child('counter').once().then((DataSnapshot snapshot) {
print('Connected to second database and read ${snapshot.value}');
});
database.setPersistenceEnabled(true);
database.setPersistenceCacheSizeBytes(10000000);
_counterRef.keepSynced(true);
_counterSubscription = _counterRef.onValue.listen((Event event) {
error = null;
_counter = event.snapshot.value ?? 0;
}, onError: (Object o) {
error = o;
});
}
DatabaseError getError() {
return error;
}
int getCounter() {
return _counter;
}
DatabaseReference getUser() {
return _userRef;
}
addUser(User user) async {
final TransactionResult transactionResult =
await _counterRef.runTransaction((MutableData mutableData) async {
mutableData.value = (mutableData.value ?? 0) + 1;
return mutableData;
});
if (transactionResult.committed) {
_userRef.push().set(<String, String>{
"Name": "" + user.name,
"date": "" + user.date,
"email": "" + user.email,
"phone": "" + user.phone,
"Place": "" + user.place,
"Club": "" + user.club,
}).then((_) {
print('Transaction committed.');
});
} else {
print('Transaction not committed.');
if (transactionResult.error != null) {
print(transactionResult.error.message);
}
}
}
void deleteUser(User user) async {
await _userRef.child(user.id).remove().then((_) async{
await _counterRef.runTransaction((MutableData mutableData) async {
mutableData.value = (mutableData.value ?? 0) - 1;
return mutableData;
});
print('Transaction committed.');
});
}
void updateUser(User user) async {
await _userRef.child(user.id).update({
"Name": "" + user.name,
"date": "" + user.date,
"email": "" + user.email,
"phone": "" + user.phone,
"Place": "" + user.place,
"Club": "" + user.club,
}).then((_) {
print('Transaction committed.');
});
}
void dispose() {
_messagesSubscription.cancel();
_counterSubscription.cancel();
}
}
Here is info from RTDB:
Datafetchfrom
counter: 2
record
0
Club:"Club1"
Name:"Name1"
Place:"City1"
date: "31737"
email:"sss#gmail.com"
phone:"98988"
2
Club:"Club2"
Name:"Name2"
Place:"City2"
date: "34334"
email:"ddd#gmail.com"
phone:"12333"
I have previously asked a question regarding lists in Flutter. I got good help but new problems arose within the same list. Since this new probelm is of other character then the initial question I made this new question.
I have a list (the code below is simplified from my working-code to make my problem clearer) of blue colored containers.
When the user types in 5 and press the 'submit'-button the color of the first container should change to green (if not 5 the button should turn red).
The second time the user press the 'submit'-button the second container should change color. And so on...
The problem I'm facing is that I can't get my increment to the list to work.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'listing 4',
theme: ThemeData(primarySwatch: Colors.blue),
home: FirstScreen(),
);
}
}
class FirstScreen extends StatefulWidget {
#override
_FirstScreenState createState() => _FirstScreenState();
}
class _FirstScreenState extends State<FirstScreen> {
int sum = 5;
String userAnswer;
String correction = "";
var _controller = new TextEditingController();
int _counter = 1;
List<Color> colors = [Colors.blue, Colors.blue, Colors.blue];
submitPressed(int index) {
if (userAnswer == sum.toString()) {
setState(() {
correction = sum.toString();
colors[index] = Colors.green;
});
} else {
setState(() {
correction = sum.toString();
colors[index] = Colors.red;
});
}
}
Widget myTextField() {
return Container(
width: 50.0,
child: TextField(
controller: _controller,
textAlign: TextAlign.center,
autofocus: true,
keyboardType: TextInputType.number,
onChanged: (val) {
userAnswer = val;
},
),
);
}
Widget myListBuilder() {
return Container(
height: 50.0,
width: 300.0,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 3,
itemBuilder: buildContainer,
),
),
);
}
Widget buildContainer(BuildContext context, int index) {
return Container(
child: Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Container(
height: 20.0,
width: 15.0,
decoration: BoxDecoration(
color: colors[index], //this is the important line
borderRadius: BorderRadius.all(Radius.circular(8.0))),
),
));
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Listing 4'),
),
body: Container(
child: Center(
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10.0),
child: Text('Correct answer is 5',
style: TextStyle(fontSize: 20.0)),
),
myTextField(),
RaisedButton(
child: Text('Submit'),
onPressed: () {
setState(() {
submitPressed(0); //This will naturally only give index 0
});
},
),
myListBuilder(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
buildContainer(context, 0),
buildContainer(context, 1),
buildContainer(context, 2)
],
),
RaisedButton(
child: Text('Next'),
onPressed: () {
_counter++;
_controller.clear();
myTextField();
},
),
Text('This should be container no: $_counter'),
],
),
),
),
);
}
}
I can't figure out why you have this
submitPressed(0);
This code works:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'listing 4',
theme: ThemeData(primarySwatch: Colors.blue),
home: FirstScreen(),
);
}
}
class FirstScreen extends StatefulWidget {
#override
_FirstScreenState createState() => _FirstScreenState();
}
class _FirstScreenState extends State<FirstScreen> {
int sum = 5;
String userAnswer;
String correction = "";
var _controller = new TextEditingController();
int _counter = 0;
List<Color> colors = [Colors.blue, Colors.blue, Colors.blue];
submitPressed(int index) {
if (userAnswer == sum.toString()) {
setState(() {
correction = sum.toString();
colors[index] = Colors.green;
});
} else {
setState(() {
correction = sum.toString();
colors[index] = Colors.red;
});
}
}
Widget myTextField() {
return Container(
width: 50.0,
child: TextField(
controller: _controller,
textAlign: TextAlign.center,
autofocus: true,
keyboardType: TextInputType.number,
onChanged: (val) {
userAnswer = val;
},
),
);
}
Widget myListBuilder() {
return Container(
height: 50.0,
width: 300.0,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 3,
itemBuilder: buildContainer,
),
),
);
}
Widget buildContainer(BuildContext context, int index) {
return Container(
child: Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Container(
height: 20.0,
width: 15.0,
decoration: BoxDecoration(
color: colors[index], //this is the important line
borderRadius: BorderRadius.all(Radius.circular(8.0))),
),
));
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Listing 4'),
),
body: Container(
child: Center(
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10.0),
child: Text('Correct answer is 5',
style: TextStyle(fontSize: 20.0)),
),
myTextField(),
RaisedButton(
child: Text('Submit'),
onPressed: () {
setState(() {
submitPressed(_counter);
});
},
),
myListBuilder(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
buildContainer(context, 0),
buildContainer(context, 1),
buildContainer(context, 2)
],
),
RaisedButton(
child: Text('Next'),
onPressed: () {
setState(() {
_counter++;
});
_controller.clear();
myTextField();
},
),
Text('This should be container no: ${_counter +1}'),
],
),
),
),
);
}
}
I changed the _counter to act like an index and use it as the parameter of the method submitPressed.
I also put the increment in a setState, or you saw the new number only after hitting the Submit button.