Flutter how i can load list from other file? - list

I want to load a list from a file into a widget, I have several lists and a specific list with an id should be loaded.
This is my code:
main
class Cars extends StatefulWidget {
#override
_carsState createState() => _carsState();
}
class _carsState extends State<cars> {
List clist = [
{'id': 'l0', 'name': 'BMW'},
{'id': 'l1', 'name': 'Audi'},
];
#override
Widget build(BuildContext context) {
return Column(
children: clist.map((info) {
return Container(
margin: EdgeInsets.all(5),
child: SizedBox(
width: double.infinity,
child: RaisedButton(
padding: EdgeInsets.all(20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0),
),
color: Colors.blue,
child: Text(
info['name'],
style: TextStyle(color: Colors.white),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Cars(name: info['name'], id: info['id'],)),
);
},
),
),
);
}).toList(),
);
}
}
cars.dart
class Cars extends StatelessWidget {
final String name;
var id;
Cars({Key key, this.name, this.id}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(name),
backgroundColor: Colors.green,
centerTitle: true,
),
body: Column(
children: LISTFROMOTHERFILE.map((info) {
return Container(
margin: EdgeInsets.all(5),
child: SizedBox(
width: double.infinity,
child: Text(info['name'])
),
);
}).toList(),
));
}
}
list.dart
List l0 = [
{'name': 'Example', 'PS': '500'},
{'name': 'Example2', 'PS': '300'},
];
List l1 = [
{'name': 'Example', 'PS': '300'},
];
Now, if, for example, the ID 1 is transferred from the main, I would like the list l0 to be loaded!
How can I realize this or is there a better way to do it?

Better to make POJO class of your list
class ExampleList{
final String id;
final String name ;
final String PS;
/// implement [fromJson] and [toJson] method if needed
}
now whenever you need of it then just pass the whole object rather than passing strings.
you can use it like this
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Cars(ExampleList:ExampleList)),
);

Related

flutter : value not passed to the previous screen and is shown null while using constructor

Basically, I have two classes Register and AddUser. I want to navigate value from the AddUser page to the RegisterPage but I am not getting any values despite using the constructor and getting null value while debugging.
User First lands on the Register page where there is floatingAction button and it navigates to the AddUser Page. After providing the input , on clicking save button, it navigates back to the Register page where user will get the list of input.
**Register**
class Register extends StatefulWidget {
late String? names;
Register({required this.names});
#override
_RegisterState createState() => _RegisterState(names);
}
class _RegisterState extends State<Register> {
late String? names;
_RegisterState(this.names);
List<UserModel> getUserModel() {
return [
UserModel(
name: widget.names??'',
)
];
}
// final user = UserSimplePreferences.getUser();
#override
void initState() {
// TODO: implement initState
super.initState();
}
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.only(top: 10, bottom: 10),
child: Text('Seleccione una categoría:',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.black)
),
),
Expanded(
child: ListView.builder(
itemCount: getUserModel().length,
itemBuilder: (BuildContext ctx, int index) {
return Container(
margin: EdgeInsets.all(20),
height: 150,
child: Stack(
children: [
Text(getUserModel()[index].name)
],
)
);
},
),
),
FloatingActionButton(
backgroundColor: Colors.indigo[900],
onPressed: () {
print(names);
Navigator.push(
context,
MaterialPageRoute(builder: (_) {
return AddUser(idUser: '',);
}),
);
},
child: Icon(Icons.add, color: Colors.white),
),
]
);
}
}
**AddUser**
class AddUser extends StatefulWidget {
final String? idUser;
const AddUser({required this.idUser});
#override
_AddUserState createState() => _AddUserState();
}
class _AddUserState extends State<AddUser> {
final formKey = GlobalKey<FormState>();
TextEditingController saaaaa = new TextEditingController();
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text(
'Please Enter Your Details',
textAlign: TextAlign.center,
)),
body: SafeArea(
child: ListView(
padding: EdgeInsets.all(16),
children: [
buildName(),
const SizedBox(height: 12),
],
),
),
);
Widget buildName() => buildTitle(
title: 'Name',
child: TextFormField(
controller: saaaaa,
//initialValue: name,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Your Name',
),
onChanged: (namer) => setState(() => namer = saaaaa.text),
),
);
Widget buildButton() => ButtonWidget(
text: 'Save',
onClicked: () async {
setState(() async {
Register(names : saaaaa.text );
Navigator.pop(context);
});
});
Widget buildTitle({
required String title,
required Widget child,
}) =>
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
title,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
),
const SizedBox(height: 8),
child,
],
);
}
You can achive this things by then callback in navigator and pass your value when you pop add screen.
Please replace your code with below code
Register
class Register extends StatefulWidget {
#override
_RegisterState createState() => _RegisterState();
}
class _RegisterState extends State<Register> {
List<UserModel> userList = [];
// final user = UserSimplePreferences.getUser();
#override
void initState() {
// TODO: implement initState
super.initState();
}
#override
Widget build(BuildContext context) {
return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
Padding(
padding: const EdgeInsets.only(top: 10, bottom: 10),
child: Text('Seleccione una categoría:',
textAlign: TextAlign.center, style: TextStyle(color: Colors.black)),
),
Expanded(
child: ListView.builder(
itemCount: userList.length,
itemBuilder: (BuildContext ctx, int index) {
return Container(
margin: EdgeInsets.all(20),
height: 150,
child: Stack(
children: [Text(userList[index].name)],
));
},
),
),
FloatingActionButton(
backgroundColor: Colors.indigo[900],
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) {
return AddUser(
idUser: '',
);
}),
).then((value) {
if (value != null) {
userList.add(UserModel(name: value));
setState(() {});
}
});
},
child: Icon(Icons.add, color: Colors.white),
),
]);
}
}
**AddUser**
class AddUser extends StatefulWidget {
final String? idUser;
const AddUser({required this.idUser});
#override
_AddUserState createState() => _AddUserState();
}
class _AddUserState extends State<AddUser> {
final formKey = GlobalKey<FormState>();
TextEditingController saaaaa = new TextEditingController();
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text(
'Please Enter Your Details',
textAlign: TextAlign.center,
)),
body: SafeArea(
child: ListView(
padding: EdgeInsets.all(16),
children: [
buildName(),
buildButton(),
const SizedBox(height: 12),
],
),
),
);
Widget buildName() => buildTitle(
title: 'Name',
child: TextFormField(
controller: saaaaa,
//initialValue: name,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Your Name',
),
onChanged: (namer) => setState(() => namer = saaaaa.text),
),
);
Widget buildButton() => ButtonWidget(
text: 'Save',
onClicked: () async {
setState(() async {
// Register(names : saaaaa.text );
Navigator.pop(context, saaaaa.text);
});
});
Widget buildTitle({
required String title,
required Widget child,
}) =>
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
title,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
),
const SizedBox(height: 8),
child,
],
);
}
This may help and work for you
Register screen
FloatingActionButton(
backgroundColor: Colors.indigo[900],
onPressed: () async {
print(names);
var result = await Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => AddUser(idUser: '')));
print(result);
names = result;
setState((){});
},
child: const Icon(Icons.add, color: Colors.white),
)
Add screen
Widget buildButton() => MaterialButton(
child: Text('Save'),
onPressed: () {
Navigator.pop(context, saaaaa.text);
});
I guess here after you can take and store in list in register page and then list down the names
You can achieve this thing by using a callback function
add Callback function to your AddUser class and on save button just call your call back function like below:
class AddUser extends StatefulWidget {
final String? idUser;
// add this to your register class
final Function(String) addedUser;
const AddUser({required this.idUser,required this.addedUser});
#override
_AddUserState createState() => _AddUserState();
}
class _AddUserState extends State<AddUser> {
final formKey = GlobalKey<FormState>();
TextEditingController saaaaa = new TextEditingController();
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text(
'Please Enter Your Details',
textAlign: TextAlign.center,
)),
body: SafeArea(
child: ListView(
padding: EdgeInsets.all(16),
children: [
buildName(),
const SizedBox(height: 12),
],
),
),
);
Widget buildButton() => ButtonWidget(
text: 'Save',
onClicked: () async {
setState(() async {
/// Just call addedUser like this
widget.addedUser(saaaaa.text);
Navigator.pop(context);
});
});
}
Simply where you are calling AddUser in Register Screen, add addedUser in the constructor of AddUser
import 'package:flutter/material.dart';
class Register extends StatefulWidget {
late String? names;
Register({required this.names});
#override
_RegisterState createState() => _RegisterState(names);
}
class _RegisterState extends State<Register> {
late String? names;
_RegisterState(this.names);
#override
Widget build(BuildContext context) {
FloatingActionButton(
backgroundColor: Colors.indigo[900],
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) {
//just add parameter to your AddUser constructor
return AddUser(idUser: '',addedUser:(value){
///In this value variable you get the value of user you added on addUser page///
print(value);
});
}),
);
},
child: Icon(Icons.add, color: Colors.white),
),
]
);
}
}

Flutter "The expression doesn't evaluate to a function, so it can't be invoked."

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.

Selecting from a dropdown list and updating the same list the same time in flutter

How do I ensure that a user does not select the same security question twice by hiding the initially selected question from appearing in the second dropdown button and vice versa in flutter?. i am making a request to the same api for the questions.
Updated the question with some code snippets. Thanks
Container(
height: 60,
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(color: Colors.black,
width: 1),
borderRadius: BorderRadius.circular(5),
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
hint: Padding(
padding: const EdgeInsets.only(left:
20.0),
child: Text(
"Security Question Two",
style: TextStyle(
color: Colors.black,
fontSize: 16,
letterSpacing: 0.3,
fontWeight: FontWeight.w300),
),
),
itemHeight: 100,
isExpanded: true,
value: dropDownSecurityQuestionTwo,
icon: Padding(
padding: const EdgeInsets.only(right:
10.0),
child:
Icon(Icons.keyboard_arrow_down_outlined),
),
iconEnabledColor: Colors.black,
iconSize: 30,
style: TextStyle(
color: Colors.black,
),
items: questions.map((value) {
return DropdownMenuItem(
value: value['ID'].toString(),
child: Padding(
padding: const EdgeInsets.only(left:
20.0),
child: Text(
value['question'].toString(),
),
),
);
}).toList(),
onChanged: (newValue) async {
setState(() {
dropDownSecurityQuestionTwo =
newValue.toString();
print(dropDownSecurityQuestionTwo);
checkSelectedQuestion();
});
},
),
),
),
void checkSelectedQuestion(){
List newQuestions = [];
for(int i = 0; i<questions.length; i++){
print(questions[i]['ID']);
questions.removeWhere((value) => value['ID'] ==
int.parse(dropDownSecurityQuestionOne!) );
newQuestions.add(questions);}
setState(() {
questions = newQuestions ;
});}
You can add a where filter to the mapping of items to each DropDownButton, depending on the selected value of the other DropDownButton. As a result of setState, the items will be recreated if anything is selected in the other DropDownButton.
Note: This is easy to implement, but not very efficient. Items will be created and filtered every time. It will work perfectly with few items, but if you would like to do something like this with many items, you might need a more efficient approach. For example keep two items lists, and only add / remove what is affected.
Check this code and adopt it to your case:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyPage(),
);
}
}
class MyPage extends StatefulWidget {
const MyPage({Key? key}) : super(key: key);
#override
State<MyPage> createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
String? _selected1;
String? _selected2;
final List<String> _set = ['Alpha', 'Bravo', 'Charlie'];
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(children: [
DropdownButton<String>(
value: _selected1,
onChanged: (String? newValue) {
setState(() {
_selected1 = newValue!;
});
},
items: _set
.map((value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
})
.where((e) => _selected2 == null || e.value != _selected2)
.toList()),
DropdownButton<String>(
value: _selected2,
onChanged: (String? newValue) {
setState(() {
_selected2 = newValue!;
});
},
items: _set
.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
})
.where((e) => _selected1 == null || e.value != _selected1)
.toList()),
]),
),
),
);
}
}

How to avoid overwriting a List Item when using the same name?

In my project the user can add and edit List Items. The Problem is, that if the user add a List item with an already existing List name, the old one gets overwritten, with the error 'Multiple widgets used the same GlobalKey'. How can I avoid that, so that the user can add multiple items with the same name?
import 'package:flutter/material.dart';
class PlanOverview extends StatefulWidget {
const PlanOverview({Key key}) : super(key: key);
#override
_PlanOverviewState createState() => _PlanOverviewState();
}
class _PlanOverviewState extends State<PlanOverview> {
List<String> plans = ['Plan A', 'Plan B'];
void addPlan(String newPlan) {
setState(() {
plans.add(newPlan);
});
Navigator.of(context).pop();
}
void newEntry() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: TextField(
onSubmitted: addPlan,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
icon: Icon(Icons.text_snippet_outlined),
labelText: 'Name des Plans'),
),
);
});
}
void edit(int i) => showDialog(
context: context,
builder: (context) {
final plan = plans[i];
return AlertDialog(
content: TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
icon: Icon(Icons.text_snippet_outlined)),
initialValue: plan,
onFieldSubmitted: (_) => Navigator.of(context).pop(),
onChanged: (name) => setState(
() {
plans[i] = name;
},
)));
});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Trainingspläne'),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.only(bottomLeft: Radius.circular(10.0), bottomRight: Radius.circular(10.0)),
),
actions: [
IconButton(
onPressed: newEntry,
icon: Icon(Icons.add),
),
],
),
body: ReorderableListView.builder(
itemCount: plans.length,
onReorder: (oldi, newi) => setState(() {
final i = newi > oldi ? newi - 1 : newi;
final plan = plans.removeAt(oldi);
plans.insert(i, plan);
}),
itemBuilder: (context, i) {
final plan = plans[i];
return ListTile(
tileColor: Color.fromARGB(255, 34, 34, 34),
key: ValueKey(plan),
contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 5),
title: Text(plans[i]),
onTap: () {
Navigator.push<Widget>(
context,
MaterialPageRoute(
builder: (context) =>
ExerciseTable(key: GlobalKey(), title: plans[i])));
},
trailing: IconButton(
icon: Icon(Icons.edit),
onPressed: () {
edit(i);
}),
);
}),
);
}
}
When the user creates an element and adds it to the list, you can check the list for an element with the same name and if it exists, add its index to its name this way there cant be two elements with the same name.
You dont need to show the index part of the name to the user if you dont want to, its just for control purposes.
If you have a search bar where the user types the name of the element he wants to access you can use auto complete to show the elements tht contains what the user is typing.

Flutter List, detail page and todo

I have a page with a list and a bar that reaches a detail page.
I would like to add a pop on the detail page to retrieve an item and save it to a todo page but I have a problem with my detail page.
With a Stateless, I have no worries but, if I'm not mistaken, I need a Stateful to add a Future, showDialog .. but, I have problems with my indexes... and there, I'm lost ...
Can someone give me a track or an explanation?
Thank you
home.dart
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:test_todo_list/DataList.dart';
import 'package:test_todo_list/detail.dart';
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Liste Items'),
actions: <Widget>[
IconButton(icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch(listWords));
})
],
),
body: ListView.separated(
itemCount: listWords.length,
separatorBuilder: (BuildContext context, int i) =>
Divider(color: Colors.grey),
itemBuilder: (context, i) {
return ListTile(
onTap: () {
Navigator.push(
context,MaterialPageRoute(
builder: (context) => Detail(listWordsDetail: listWords[i]),
),
);
},
title: RichText(
textAlign:TextAlign.left,
text: TextSpan(
children:<TextSpan>[
TextSpan(
text:listWords[i].titlelist,
style:Theme.of(context).textTheme.title.merge(TextStyle(color: Colors.blueGrey)),
),
]
)
),
subtitle: Text(listWords[i].definitionlist,
style: Theme.of(context).textTheme.subtitle.merge(
TextStyle(fontStyle: FontStyle.italic, color: Colors.grey)),
),
trailing: Icon(Icons.arrow_forward_ios, color: Colors.grey),
);
},
),
);
}
}
class DataSearch extends SearchDelegate<String> {
final List<ListWords> listWords;
DataSearch(this.listWords);
#override
List<Widget> buildActions(BuildContext context) {
//Actions for app bar
return [IconButton(icon: Icon(Icons.clear), onPressed: () {
query = '';
})];
}
#override
Widget buildLeading(BuildContext context) {
//leading icon on the left of the app bar
return IconButton(
icon: AnimatedIcon(icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
});
}
#override
Widget buildResults(BuildContext context) {
// show some result based on the selection
final suggestionList = listWords;
return ListView.builder(itemBuilder: (context, index) => ListTile(
title: Text(listWords[index].titlelist),
subtitle: Text(listWords[index].definitionlist),
),
itemCount: suggestionList.length,
);
}
#override
Widget buildSuggestions(BuildContext context) {
// show when someone searches for something
final suggestionList = query.isEmpty
? listWords
: listWords.where((p) => p.titlelist.contains(RegExp(query, caseSensitive: false))).toList();
return ListView.builder(itemBuilder: (context, index) => ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Detail(listWordsDetail: suggestionList[index]),
),
);
},
trailing: Icon(Icons.remove_red_eye),
title: RichText(
text: TextSpan(
text: suggestionList[index].titlelist.substring(0, query.length),
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: suggestionList[index].titlelist.substring(query.length),
style: TextStyle(color: Colors.grey)),
]),
),
),
itemCount: suggestionList.length,
);
}
}
detail.dart
import 'package:flutter/material.dart';
import 'package:test_todo_list/DataList.dart';
class Detail extends StatefulWidget {
Detail({Key key, #required this.listWordsDetail}) : super(key: key);
final ListWords listWordsDetail;
#override
_DetailState createState() => _DetailState();
}
class _DetailState extends State<Detail> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
brightness: Brightness.dark,
title: const Text('Détails', style: TextStyle(color: Colors.white)),
iconTheme: IconThemeData(color: Colors.white),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(listWordsDetail.titlelist +' (on detail page)',
style:Theme.of(context).textTheme.title.merge(TextStyle(color: Colors.blueGrey)),
),
Text(listWordsDetail.definitionlist,
style: Theme.of(context).textTheme.subtitle.merge(
TextStyle(fontStyle: FontStyle.italic, color: Colors.grey)),
),
Container(
padding: EdgeInsets.all(40.0),
child: GestureDetector(
onTap: () {
},
child: Icon(Icons.add_shopping_cart),
),
)
],
),
)
);
}
}
DataList.dart
List<ListWords> listWords = [
ListWords('oneWord', 'OneWord definition'),
ListWords('twoWord', 'TwoWord definition.'),
ListWords('TreeWord', 'TreeWord definition'),
];
class ListWords {
String titlelist;
String definitionlist;
ListWords(String titlelist, String definitionlist) {
this.titlelist = titlelist;
this.definitionlist = definitionlist;
}
}
After searching on the web, by chance, I found this solution that I can not explain but it's working...
import 'package:flutter/material.dart';
import 'package:test_todo_list/DataList.dart';
import 'package:test_todo_list/todo_list.dart';
class Detail extends StatefulWidget {
const Detail({Key key, this.listWordsDetail}) : super (key: key);
final ListWords listWordsDetail;
#override
_DetailState createState() => _DetailState();
}
class _DetailState extends State<Detail> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
brightness: Brightness.dark,
title: const Text('Détails', style: TextStyle(color: Colors.white)),
iconTheme: IconThemeData(color: Colors.white),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(widget.listWordsDetail.titlelist),
Text(widget.listWordsDetail.definitionlist),
Container(
padding: EdgeInsets.all(40.0),
child: GestureDetector(
onTap: () {
//open Dialog addTodoList()
},
child: Icon(Icons.add_shopping_cart),
),
)
],
),
)
);
}
Future<Null> addTodoList() async {
showDialog(context: context);
//... à construire
}
}