Search in ListView (with Data from Firebase) in Flutter - android

I'm trying to implement a search function into my app. Right now I got a ListView, which displays the data I get from a Firebase Database as a Stream. Do you have any Ideas how to search this List?
Here is my code for the ListView:
import "package:rate_my_food_1/models/imbiss.dart";
import "package:provider/provider.dart";
import "package:rate_my_food_1/widgets/imbiss_tile.dart";
class ImbissList extends StatefulWidget {
#override
_ImbissListState createState() => _ImbissListState();
}
class _ImbissListState extends State<ImbissList> {
#override
Widget build(BuildContext context) {
final imbiss = Provider.of<List<Imbiss>>(context);
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(hintText: "Suchen...", hintStyle: TextStyle(color: Colors.white)),
style: TextStyle(color: Colors.white),
),
),
SizedBox(height: 10,),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: imbiss.length ?? 0,
itemBuilder: (context, index){
return ImbissTile(imbiss: imbiss[index]);
},
),
),
],
);
}
}
And here is how I implemented the ListView in my homescreen of the App:
import 'package:rate_my_food_1/models/imbiss.dart';
import "package:rate_my_food_1/services/database.dart";
import "package:provider/provider.dart";
import "package:rate_my_food_1/widgets/imbiss_list.dart";
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return StreamProvider<List<Imbiss>>.value(
value: DatabaseService().imbisses,
child: Scaffold(
backgroundColor: Colors.grey[800],
//Add Button
floatingActionButton: FloatingActionButton(
onPressed: (){
Navigator.pushNamed(context, "/add");
},
child: Icon (Icons.add),
backgroundColor: Colors.cyanAccent,
),
body: Column(
children: <Widget>[
SafeArea(child: SizedBox(height: 10.0,)),
//Imbissliste
Expanded(child: ImbissList()),
],
)
)
);
}
}
I was thinking about making a second List in which I can Filter only for objects which contain what I'm writing into the TextField, but I have no clue how to do that properly.
Do you have any Ideas on how to search in this ListView?
If you need any more code from my Project, please let me know.
Thanks for all answers!
Yoqora
EDIT:
This is my Code atm, with the problem that it doesn't show the ListView and TextField when I start the app:
import "package:rate_my_food_1/models/imbiss.dart";
import "package:provider/provider.dart";
import "package:rate_my_food_1/widgets/imbiss_tile.dart";
class ImbissList extends StatefulWidget {
#override
_ImbissListState createState() => _ImbissListState();
}
class _ImbissListState extends State<ImbissList> {
List<Imbiss> imbiss = [];
List<Imbiss> filteredImbiss = [];
#override
initState() {
imbiss = Provider.of<List<Imbiss>>(context);
filteredImbiss = imbiss;
super.initState();
}
#override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(hintText: "Suchen...", hintStyle: TextStyle(color: Colors.white)),
style: TextStyle(color: Colors.white),
onChanged: (value) {
setState(() {
filteredImbiss = imbiss.where((imbiss) => imbiss.name.contains(value)).toList();
});
},
),
),
SizedBox(height: 10,),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: filteredImbiss.length,
itemBuilder: (context, index){
return ImbissTile(imbiss: filteredImbiss[index]);
},
),
),
],
);
}
}`

We can filter the retrieved data using a key in state. This key kan be updated using the onChanged(String) method from the TextField widget. We simply filter the list on every build, please see the example below:
class ImbissList extends StatefulWidget {
#override
_ImbissListState createState() => _ImbissListState();
}
class _ImbissListState extends State<ImbissList> {
// The search key to filter the imbisses.
String key = '';
#override
Widget build(BuildContext context) {
var imbisses = Provider.of<List<Imbiss>>(context);
// Filter the imbisses using the key.
imbisses = imbisses.where((imbiss) {
return imbiss.name.contains(key);
}).toList();
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(
hintText: "Suchen...",
hintStyle: TextStyle(color: Colors.white)),
style: TextStyle(color: Colors.white),
onChanged: (value) {
// Update the key when the value changes.
setState(() => key = value);
},
),
),
SizedBox(
height: 10,
),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: imbisses.length,
itemBuilder: (context, index) {
return ImbissTile(imbiss: imbisses[index]);
},
),
),
],
);
}
}

Hey i tried the same thing but i'm getting a blank screen, if possible can you please share the source code.
Edit: I figured out where i was going wrong. Thank you so much for the solution this was really helpful

Related

Integrating Hive with Flutter for local data copy

I am trying the code put by Resocoder for integrating the Hive with Flutter. Everything was going fine but i got stuck at a place from where i cant figure out what to do. If you see contactsbox is throwing error stating that itsa n object and i cant use lingth property on it or even any other property. I have market the partof the code in bold throwing error. Any idea why is this error happening. HOw shall i use contactsBox as List unable to understand it. Any help would be great
contact_page.dart
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'new_contact_form.dart';
import 'contact.dart';
class ContactPage extends StatelessWidget {
const ContactPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hive Tutorial'),
),
body: Column(
children: [
Expanded(
child: _buildListView(),
),
NewContactForm(),
],
),
);
}
Widget _buildListView() {
return ValueListenableBuilder(
valueListenable: Hive.box('contacts').listenable(), builder:
(context, contactsBox, _) {
return ListView.builder(**itemCount: contactsBox.length** , itemBuilder: (context, index) {
final contact = contactsBox.getAt(index) as Contact;
return ListTile(
title: Text(contact.name!),
subtitle: Text(contact.age.toString()),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
contactsBox!.putAt(
index,
Contact('${contact.name}*', contact.age + 1),
);
},
),
IconButton(
icon: Icon(Icons.delete),
onPressed: () {
contactsBox.deleteAt(index);
},
)
],
),
);
}
);
}
);
}
new_contact_form.dart
import 'package:db_app/contact.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
class NewContactForm extends StatefulWidget {
const NewContactForm({Key? key}) : super(key: key);
#override
State<NewContactForm> createState() => _NewContactFormState();
}
class _NewContactFormState extends State<NewContactForm> {
final _formKey = GlobalKey<FormState>();
String? _name;
String? _age;
void addContact(Contact cnt) {
final contactBox = Hive.box('contacts');
contactBox.add(cnt);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Form(
child: Column(
children: [
TextFormField(
decoration: InputDecoration(labelText: 'Name'),
onSaved: (value) => _name = value,
),
SizedBox(height: 10),
TextFormField(
decoration: InputDecoration(labelText: 'Age'),
onSaved: (value) => _age = value,
keyboardType: TextInputType.number,
),
ElevatedButton(
onPressed: () {
_formKey.currentState!.save();
final newContact = Contact(_name, int.parse(_age!));
addContact(newContact);
},
child: Text('Add New Contact'),
),
],
),
));
}
}

LateInitializationError: Field has not been initialized in Flutter

I'm considerably new to Flutter and I'm to build a Messenger Chap App on Flutter, and I face the issue of "LateInitilization: Field 'searchSnapShot' has not been initialized. Following is the snippet of code that is causing the issue:
Widget searchList() {
return searchSnapShot != null ? ListView.builder(
itemCount: searchSnapShot.docs.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return SearchTile(
userName: searchSnapShot.docs[index].data()["name"],
userEmail: searchSnapShot.docs[index].data()["email"],
);
}
) : Container();
}
What this snippet is supposed to do is return a list of users that match the search query. Following is the code for the entire search.dart:
import 'package:chat_app/services/database.dart';
import 'package:chat_app/widgets/widgets.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class SearchScreen extends StatefulWidget {
#override
_SearchScreenState createState() => _SearchScreenState();
}
class _SearchScreenState extends State<SearchScreen> {
DatabaseMethods databaseMethods = new DatabaseMethods();
TextEditingController searchTextEditingController = new TextEditingController();
late QuerySnapshot <Map<String, dynamic>> searchSnapShot;
initiateSearch() async {
await databaseMethods
.getUserByUsername(searchTextEditingController.text)
.then((val) {
setState(() {
searchSnapShot = val;
});
});
}
Widget searchList() {
return searchSnapShot != null ? ListView.builder(
itemCount: searchSnapShot.docs.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return SearchTile(
userName: searchSnapShot.docs[index].data()["name"],
userEmail: searchSnapShot.docs[index].data()["email"],
);
}
) : Container();
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: appBarMain(context),
body: Container(
child: Column(
children: [
Container(
color: Color(0xffFFC200),
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 16),
child: Row(
children: [
Expanded(
child: TextField(
controller: searchTextEditingController,
decoration: InputDecoration(
hintText: "search username..",
hintStyle: TextStyle(
color: Colors.black,
),
border: InputBorder.none,
),
)
),
GestureDetector(
onTap: () {
initiateSearch();
},
child: Container(
height: 30,
child: Image.asset("assets/images/search_white.png")),
),
],
),
),
searchList()
],
),
),
);
}
}
class SearchTile extends StatelessWidget {
late final String userName;
late final String userEmail;
SearchTile({required this.userName, required this.userEmail});
#override
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Column(
children: [
Text(
userName,
style: simpleTextStyle()
),
Text(
userEmail,
style: simpleTextStyle(),
),
],
),
Spacer(),
Container(
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.circular(40)
),
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text("Message"),
)
],
),
);
}
}
Error Description in Android Studio:
======== Exception caught by widgets library =======================================================
The following LateError was thrown building SearchScreen(dirty, state: _SearchScreenState#f41e2):
LateInitializationError: Field 'searchSnapShot' has not been initialized.
What am I doing wrong here? I'd really appreciate some help. Thank you.
When you use late it means that variable can be lazily initialised, So, before use it somewhere, you need to Initialise thus you cannot make null checks on that, If you want to make null checks on it then try ? which makes that variable a nullable.
So remove late and add ?
QuerySnapshot <Map<String, dynamic>>? searchSnapShot;
initialize searchSnapshot using:
QuerySnapshot<dynamic>? searchSnapshot;
also, add null checks in searchTitle:
SearchTitle(
userName: searchSnapshot!.docs[index].data()['name'],
userEmail: searchSnapshot!.docs[index].data()['email'],
);SearchTitle(
userName: searchSnapshot!.docs[index].data()['name'],
userEmail: searchSnapshot!.docs[index].data()['email'],
);
Try this please
QuerySnapshot? <Map<String, dynamic>> searchSnapShot;
If you're using a setter under class make sure that the parameter in your setter is different from the variable you're initializing
Coupon? coupon;
void setCoupon(Coupon myCoupon){
coupon = myCoupon;
}

Flutter error when passing data from one view to another. Error type 'Song' is not a subtype of type 'Song'

am trying to pass song details from the following file Songs_list.dart to home_screen.dart but i get an error that type 'Song' is not a subtype of type 'song' where Song is from .......Songs_list.dart
import 'package:flutter/material.dart';
import 'package:nyimbo_cia_ngai/models/Songs_All.dart';
import 'package:nyimbo_cia_ngai/screens/home_screen.dart';
class SongsList extends StatefulWidget {
//static String tag = 'Songlist-page';
#override State<StatefulWidget> createState() {
return new _SongsListState();
}
}
class _SongsListState extends State<SongsList> {
TextEditingController searchController = new TextEditingController();
String filter;
#override initState() {
searchController.addListener(() {
setState(() {
filter = searchController.text;
});
});
}
#override void dispose() {
searchController.dispose();
super.dispose();
}
#override Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
appBar: AppBar( leading: IconButton(
icon: Icon(Icons.menu),
iconSize: 30.0,
color: Colors.white,
onPressed: (){},
),
title: Text('Nyimbo Cia Kuinira Ngai', style: TextStyle(fontSize: 20.0,
),),
elevation: 0.0,
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
iconSize: 30.0,
color: Colors.white,
onPressed: (){},
),
],
),
body: new Column(
children: <Widget>[
//Search box
new Padding(
padding: new EdgeInsets.all(8.0),
child: new TextField(
controller: searchController,
decoration: InputDecoration(
hintText: 'Search Song',
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0),
borderSide: BorderSide(color: Colors.white)
),
),
),
//search Box end
),
new Expanded(
child: Container(
decoration: BoxDecoration(color: Theme.of(context).accentColor,
borderRadius: BorderRadius.only(topLeft: Radius.circular(30.0),topRight: Radius.circular(30.0),
),
),
///////////////////////////////////////////////////////////////////
child: new ListView.builder(
itemCount: Songs.length,
itemBuilder: (context, index) {
// if filter is null or empty returns all data
return filter == null || filter == "" ? ListTile(
title: Text(
'${Songs[index].SongName}',
),
subtitle: Text('${Songs[index].SongNumber}'),
leading: new CircleAvatar(
backgroundColor: Theme.of(context).primaryColor,
child: Text(
'${Songs[index].SongNumber.substring(0, 3)}')),
onTap: () =>
Navigator.push(context, MaterialPageRoute(builder: (context)=>HomeScreen(Songs[index] ?? '')))
//_onTapItem(context, Songs[index] ?? ''),
)
: '${Songs[index].SongNumber}'.toLowerCase()//search using the song number
.contains(filter.toLowerCase())
? ListTile(
title: Text(
'${Songs[index].SongName}',
),
subtitle: Text('${Songs[index].SongNumber}'),
leading: new CircleAvatar(
backgroundColor: Theme.of(context).primaryColor,
child: Text(
'${Songs[index].SongNumber.substring(0, 3)}')),
onTap: () =>
Navigator.push(context, MaterialPageRoute(builder: (context)=>HomeScreen(Songs[index]?? '')))
//_onTapItem(context, Songs[index]?? ''),
)
: new Container();
},
),
//////////////////////////////////////////////////////////////////
),
),
],
));
}
void _onTapItem(BuildContext context, Song post) {
}
}
class Song {
final String SongNumber;
final String SongName;
const Song({this.SongNumber, this.SongName});
}
Songs_list.dart is getting its data from Songs_all.dart which is happening correctly
import 'package:flutter/material.dart';
class Song{
String SongName;
String SongNumber;
String verses;
Song(
{
#required this.SongName,
#required this.SongNumber,
#required this.verses});
}
List<Song> Songs =[
Song(
SongNumber:'002',
SongName:'HE NYUMBA NJEGA THIINI WA ANDU',
verses:'1 . He nyumba njega thiini wa andu'
But when user taps on the song to open its details it brings up an error. the ontap is supposed to open in the following page home_screen.dart
import 'package:flutter/material.dart';
import 'package:nyimbo_cia_ngai/screens/Songs_list.dart';
class HomeScreen extends StatelessWidget {
final Song song;
HomeScreen(this.song);
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(''),
),
);
}
}
where could i be going wrong when passing the details using ontap?
You are using diffrent class "Song"
SongsList : import 'package:nyimbo_cia_ngai/models/Songs_All.dart';
HomeScreen : import 'package:nyimbo_cia_ngai/screens/Songs_list.dart';
Its not big issue just make sure you are importing the same class.

How to show the fetched data from api on a button click in flutter?

I want to show the fetched love calculator data after button click but how to visible it? Please answer
import 'dart:io';
import 'package:AllInOneCalci/CustomTextField.dart';
import 'package:AllInOneCalci/Post.dart';
import 'package:AllInOneCalci/customAppBar.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
class LoveCalUI extends StatelessWidget {
#override
Widget build(BuildContext context) {
var AppBarHeight = MediaQuery.of(context).size.height;
return Scaffold(
appBar: customAppBar(
height: (AppBarHeight / 3) * 0.4,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top: 18.0),
child: Text(
'All In One Cali',
style: TextStyle(
color: Colors.black,
fontSize: 35.0,
fontFamily: 'DancingScript',
fontWeight: FontWeight.bold),
),
),
],
),
),
body: CustomFetchData(),
);
}
}
class CustomFetchData extends StatefulWidget {
#override
_CustomFetchDataState createState() => _CustomFetchDataState();
}
class _CustomFetchDataState extends State<CustomFetchData> {
TextEditingController firstNameController = new TextEditingController();
TextEditingController secondNameController = new TextEditingController();
Future<Post> getData() async {
final response = await http.get(
'https://love-calculator.p.rapidapi.com/getPercentage?fname=aalia&sname=Alice',
headers: {
'x-rapidapi-host': 'love-calculator.p.rapidapi.com',
'x-rapidapi-key':
'84e84770b9msh59a96d8b03cb4aap1615a1jsn1cd0ef******',
});
if (response.statusCode == 200) {
return Post.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load api');
}
}
Widget ErrorDesign() {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
alignment: Alignment.center,
child: Text(
'Error: Kindly Connect to Internet',
style: TextStyle(
color: Colors.redAccent,
fontFamily: 'DancingScript',
fontSize: 40.0,
fontWeight: FontWeight.bold,
),
),
),
);
}
Widget DisplayData(String percentageValue, String result) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
height: 100.0,
color: Colors.black,
child: Column(
children: [
Text('Percentage is $percentageValue',
style: TextStyle(
color: Colors.white,
)),
Text('Result is: $result',
style: TextStyle(
color: Colors.white,
)),
],
),
),
);
}
Widget FetchedCalculationValues() {
return Column(
children: [
Container(
child: FutureBuilder<Post>(
future: getData(),
builder: (BuildContext context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: CircularProgressIndicator(),
),
);
} else {
if (snapshot.hasError) {
return Container(
child: ErrorDesign(),
);
} else {
return DisplayData(
snapshot.data.percentage, snapshot.data.result);
}
}
})),
],
);
}
#override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0, top: 15.0),
child: CustomTextField('First Name', "", Colors.cyan,
Colors.cyanAccent, Colors.redAccent, firstNameController),
),
Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0),
child: CustomTextField('Second Name', "", Colors.red,
Colors.redAccent, Colors.cyanAccent, secondNameController),
),
Padding(
padding: const EdgeInsets.all(18.0),
child: MaterialButton(
color: Colors.redAccent,
child: Text(
'Result',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {
FetchedCalculationValues();
print('Fetch Calling');
}),
),
Visibility(
visible: false,
child: FetchedCalculationValues(),
),
],
);
}
#override
// ignore: must_call_super
void initState() {
getData();
}
}
How to make the function for api call visible to the screen after button click.
Also I want to use the text field's values at the place of defalut values
Can you solve my problem? It will be very helpful if you do so. I am a newbie and learning flutter since 15 days. Help me so that I can learn it fast. Also the flutter's community is growing fast so it will be easy for me not to wait for response. Thank You.
I have created simplified, single-screen, app without any extra capabilities to solve exactly your issue. It contains two text fields, two Text widgets to display API results and a floating action button to make request.
Key concepts that you should know to make this code are http requests and asynchronous coding. Those links are good starting points for you to get a sense of what actually happens
To summarize what exactly you need:
You send request asynchronously to the API declaring function with async keyword and await keyword in front of http.get() function. This allows you to wait for the result of the request without freezing the app
When result comes back, the rest of the _getNames() function gets executed, which includes setState(). setState() rebuilds your widget and updates values in Text() widgets
Full code:
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
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> {
int percentage = 0;
String resultString = "";
Map<String, String> requestHeaders = {
'x-rapidapi-host': 'love-calculator.p.rapidapi.com',
'x-rapidapi-key': 'your API key',
};
final name1Controller = TextEditingController();
final name2Controller = TextEditingController();
void _getNames({String name1, String name2}) async {
final response = await http.get(
'https://love-calculator.p.rapidapi.com/getPercentage?fname=$name1&sname=$name2',
// Send authorization headers to the backend.
headers: requestHeaders,
);
final responseJson = json.decode(response.body);
setState(() {
percentage = int.parse(responseJson['percentage']);
resultString = responseJson['result'];
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: name1Controller,
decoration: InputDecoration(
hintText: "name 1",
),
),
TextField(
controller: name2Controller,
decoration: InputDecoration(
hintText: "name 2",
),
),
SizedBox(
height: 10,
),
Text(
'Your Score is: $percentage',
),
Text(
'$resultString',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_getNames(
name1: name1Controller.text,
name2: name2Controller.text,
);
},
tooltip: 'Increment',
child: Text('Go'),
),
);
}
}

Stuck on being able to view detailed information from a list in flutter app

I have a louded information in RealTime database in format for example:
record
0
Club: "Club1"
Name: "Ronaldo"
Place: "London"
date: "25.07.2020"
email: "flutter#gmail.com"
phone: "12345678"
I have created a list that consists of names and clubs and I want to go to the full information according to the form by clicking on the Name, but I can't write the code. Please help to the new programmer
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:.../anketa/tile.dart';
class Anketa extends StatefulWidget {
Anketa({Key key, this.title}) : super(key: key);
final String title;
#override
_AnketaState createState() => _AnketaState();
}
class _AnketaState extends State<Anketa> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Registration form",
style: TextStyle(
fontWeight: FontWeight.w200,
fontSize: 30,
fontFamily: 'Roboto',
fontStyle: FontStyle.italic)),
RegisterStudent(),
]),
)),
);
}
}
class RegisterStudent extends StatefulWidget {
RegisterStudent({Key key}) : super(key: key);
#override
_RegisterStudentState createState() => _RegisterStudentState();
}
class _RegisterStudentState extends State<RegisterStudent> {
final _formKey = GlobalKey<FormState>();
final listOfClubs = ["Club1", "Club2", "Club3", "Club4"];
String dropdownValue = "Club1";
final clubController = TextEditingController();
final nameController = TextEditingController();
final placeController = TextEditingController();
final dateController = TextEditingController();
final emailController = TextEditingController();
final phoneController = TextEditingController();
final rawController = TextEditingController();
final dbRef = FirebaseDatabase.instance.reference().child("record");
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(children: <Widget>[
Padding(
padding: EdgeInsets.all(20.0),
child: TextFormField(
controller: nameController,
decoration: InputDecoration(
labelText: "EnterName",
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
// The validator receives the text that the user has entered.
validator: (value) {
if (value.isEmpty) {
return "Enter name";
}
return null;
},
),
),
Padding(
padding: EdgeInsets.all(20.0),
child: DropdownButtonFormField(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
decoration: InputDecoration(
labelText: "Club",
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
items: listOfClubs.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
this.dropdownValue = newValue;
});
},
validator: (value) {
if (value.isEmpty) {
return 'Club';
}
return null;
},
),
),
Padding(
padding: EdgeInsets.all(20.0),
child: TextFormField(
keyboardType: TextInputType.number,
controller: dateController,
decoration: InputDecoration(
labelText: "Date",
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
// The validator receives the text that the user has entered.
validator: (value) {
if (value.isEmpty) {
return 'Date';
}
return null;
},
),
),
Padding(
padding: EdgeInsets.all(20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
color: Colors.lightBlue,
onPressed: () {
if (_formKey.currentState.validate()) {
dbRef.push().set({
"Name": nameController.text,
"date": dateController.text,
"Club": dropdownValue
}).then((_) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Add')));
dateController.clear();
nameController.clear();
}).catchError((onError) {
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text(onError)));
});
}
},
child: Text('Enter'),
),
RaisedButton(
color: Colors.amber,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ListOfNames()),
);
},
child: Text('Go to'),
),
],
)),
])));
}
#override
void dispose() {
super.dispose();
dateController.dispose();
nameController.dispose();
}
}
and this is the second page with a list, from where I want to go to full information
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
class ListOfNames extends StatelessWidget {
final dbRef = FirebaseDatabase.instance.reference().child("record");
List<Map<dynamic,dynamic>> lists = List();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade300,
appBar: AppBar(
backgroundColor: Colors.deepPurple,
title: Text("List of students"),
),
body: StreamBuilder(
stream: dbRef.onValue,
builder: (context, AsyncSnapshot<Event> snapshot) {
if (snapshot.hasData) {
lists.clear();
DataSnapshot dataValues = snapshot.data.snapshot;
Map<dynamic, dynamic> values = dataValues.value;
values.forEach((key, values) {
lists.add(values);
});
return new ListView.builder(
shrinkWrap: true,
itemCount: lists.length,
itemBuilder: (BuildContext context, int index) {
itemBuilder: (BuildContext context, int index) {
return ListTile(
title:Text(lists[index]["Name"], style: TextStyle(height: 2.5, fontSize:20.0),),
subtitle:Text(lists[index]['Club'], style: TextStyle(fontSize:16.0),),
onTap: (){
// in this line i have a problem...
Navigator.push(context, MaterialPageRoute(builder: (context) => DetailPage(snapshot.data[index]['Name']),
)
);
},
);
});
}
return CircularProgressIndicator();
})
);
}
}
I want to create such a page:
class DetailPage extends StatelessWidget {
List<Map<dynamic,dynamic>> data ;
DetailPage ({this.data});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(data.name),
// here I want to show the all information from the form about one person from the list
),
);
}
}
In the body of the scaffold of 'DetailsPage' use 'Card' widget with 'Text' widgets to show the info. Like Card(child:Text('${data.clubLoc}').

Categories

Resources