how to manage list string to make condition - list

Hello I tried to make an action if I have _accelerometerValuesx > value
but when I use symbole like > but I have this issue : the operator ">" isn't define is the class list
example:
if ( _accelerometerValuesx >= 2.0){
//action
}
my code :
List<double> _accelerometerValuesx;
List<StreamSubscription<dynamic>> _streamSubscriptions =
<StreamSubscription<dynamic>>[];
#override
Widget build(BuildContext context) {
final List<String> accelerometerx =
_accelerometerValuesx?.map((double v) => v.toStringAsFixed(1))?.toList();
return Scaffold(
appBar: AppBar(
title: const Text('Sensor Example'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Accelerometerx: $accelerometerx'),
],
),
padding: const EdgeInsets.all(16.0),
),
],
),
);
}
#override
void initState() {
super.initState();
_streamSubscriptions
.add(accelerometerEvents.listen((AccelerometerEvent event) {
setState(() {
_accelerometerValuesx = <double>[event.x];
});
}));
}

You need to pick a specific element from the list
if ( _accelerometerValuesx[0] >= 2.0){
//action
}
where _accelerometerValuesx[0] reads the first entry of the _accelerometerValuesx list and compares that with 2.0

Related

Flutter - list inside a list builder

I don't have much experience with flutter.
I would like to use the language_tool library for Dart and Flutter.
I created the script below:
void main() => runApp(mainApp());
class mainApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Chat(),
);
}
}
class Chat extends StatefulWidget {
const Chat({Key? key}) : super(key: key);
#override
_ChatState createState() => _ChatState();
}
class _ChatState extends State<Chat> {
String text = 'Henlo i am Gabriele';
Future<List<WritingMistake>> tool(String text) async {
var tool = LanguageTool();
var result = tool.check(text);
var correction = await result;
print(correction);
List<WritingMistake> mistakes = [];
for (var m in correction) {
//var mistake = m.issueDescription;
WritingMistake mistake = WritingMistake(
message: m.message,
offset: m.offset,
length: m.length,
issueType: m.issueType,
issueDescription: m.issueDescription,
replacements: m.replacements,
);
mistakes.add(mistake);
}
print(mistakes.length);
print(mistakes);
return mistakes;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Colors.red,
height: 150.0,
width: double.infinity,
child:
Center(child: Text(text, style: TextStyle(fontSize: 20.0))),
),
Text(
'\n Tap on the blue button to replace it in the message.\n',
),
FutureBuilder(
future: tool(text),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text('Loading...'),
),
);
} else {
return SizedBox(
height: 200.0,
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Row(
children: [
Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(' ' +
(index + 1).toString() +
' '),
Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(text.substring(
snapshot.data[index].offset,
snapshot.data[index].offset +
snapshot
.data[index].length)),
),
color: Colors.blue,
),
],
),
Icon(
Icons.arrow_forward,
),
Text(snapshot.data[index].issueDescription)
],
),
// Todo: Row with List of .replacements
],
),
),
// snapshot.data[index].issueDescription),
);
},
),
);
}
},
),
Expanded(child: Container(color: Colors.grey))
],
),
),
);
}
}
And it currently looks like this:
And I would like it to become like in this screen, but I would like the green containers derive from the WritingMistake.replacements list (with each element of the list as text):
Do you know how I can do it?
Spent several hours doing exactly what you wanted. My Code:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:language_tool/language_tool.dart';
void main() => runApp(mainApp());
class mainApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Chat(),
);
}
}
class Chat extends StatefulWidget {
const Chat({Key? key}) : super(key: key);
#override
_ChatState createState() => _ChatState();
}
class _ChatState extends State<Chat> {
String text = 'Henlo i am Gabriele';
static List<WritingMistake> mistakes = []; // Moved Here And Init Like Static
Future<List<WritingMistake>> tool(String text) async {
var tool = LanguageTool();
var result = tool.check(text);
var correction = await result;
print(correction);
for (var m in correction) {
//var mistake = m.issueDescription;
WritingMistake mistake = WritingMistake(
message: m.message,
offset: m.offset,
length: m.length,
issueType: m.issueType,
issueDescription: m.issueDescription,
replacements: m.replacements,
);
mistakes.add(mistake);
}
print(mistakes.length);
print(mistakes);
return mistakes;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Colors.red,
height: 150.0,
width: double.infinity,
child: Center(
child: Text(text, style: const TextStyle(fontSize: 20.0))),
),
const Text(
'\n Tap on the blue button to replace it in the message.\n',
),
FutureBuilder(
future: tool(text),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return const Center(
child: Text('Loading...'),
);
} else {
return SizedBox(
height: 200.0,
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int mistakeIdIndex) {
return Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Row(
children: [
Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(' ' +
(mistakeIdIndex + 1).toString() +
' '),
Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(text.substring(
snapshot.data[mistakeIdIndex]
.offset,
snapshot.data[mistakeIdIndex]
.offset +
snapshot
.data[mistakeIdIndex]
.length)),
),
color: Colors.blue,
),
],
),
const Icon(
Icons.arrow_forward,
),
Text(snapshot
.data[mistakeIdIndex].issueDescription)
],
),
// Todo: Row with List of .replacements
SizedBox(
width: MediaQuery.of(context)
.size
.width, // Width = Screen Width
height: 44,
child: ListView.builder(
itemCount: mistakes.length,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (BuildContext context,
int replacementsListIndex) {
return buildReplacements(mistakeIdIndex,
replacementsListIndex);
}),
)
],
),
),
// snapshot.data[index].issueDescription),
);
},
),
);
}
},
),
Expanded(child: Container(color: Colors.grey))
],
),
),
);
}
Widget buildReplacements(int mistakeIdIndex, int replacementsListIndex) {
if (mistakes[replacementsListIndex].replacements!.length == null) {
return const SizedBox(); // Return Empty If No Replacements Found, Just To Be Safe
}
// Check For Mistake ID - Remove This Will Cause A Problem with Displaying All Replacements Under All Words
if (mistakeIdIndex == replacementsListIndex) {
// If Only 1 Replacement, No Need To Create ListView.builder
if (mistakes[replacementsListIndex].replacements!.length == 1) {
return Container(
margin: const EdgeInsets.all(4),
padding: const EdgeInsets.all(8),
decoration: const BoxDecoration(
color: Color.fromARGB(255, 174, 213, 130)), // Green Color
child: Text(
mistakes[replacementsListIndex].replacements!.toString(),
style: const TextStyle(),
textAlign: TextAlign.center,
),
);
}
// Create ListView.builder to Create A Split Between Replacements To One Wrong-Word (Every Replacement Has It's Own Container With Green Background)
else {
return ListView.builder(
itemCount: mistakes[replacementsListIndex].replacements!.length,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.all(4),
padding: const EdgeInsets.all(8),
decoration: const BoxDecoration(
color: Color.fromARGB(255, 174, 213, 130)), // Green Color
child: Text(
mistakes[replacementsListIndex]
.replacements![index]!
.toString(),
style: const TextStyle(),
textAlign: TextAlign.center,
),
);
});
}
}
// If Replacement Not For This Wrong-Word, Then Skip
else {
return const SizedBox();
}
}
}
And Screenshot:

Adding words to the list in the correct order

I'm trying to adjust the words to form the sentence in the correct order. Like this. Or like Duolingo sentence examples. (without drag and drop, just lists and/or maps)
Sentence:
static String mySentence = "My cat is black";
static List<String> correctWords = mySentence.split(" ");
static List<String> shuffleWords = [...correctWords]..shuffle();
Green part: shuffleWidgetList. A widget has been added to each word in the shuffleWords.
List<Widget> shuffleWidgetList = [];
generateShuffleWidgets() {
for (int i = 0; i < shuffleWords.length; i++) {
shuffleWidgetList.add(shuffleWordWidget(shuffleWords[i]));
}
}
Blue part: answerWidgetList.
List<Widget> answerWidgetList = [];
White part: The answer is checked with the button.
I am comparing the list of words (List<String>) correctWords with answerWords.
onTap: () {
if (IterableEquality().equals(correctWords, answerWords)) {
print("correct");
} else {
print("wrong");
}
},
Steps:
1. In the green part, I choose a word from the list. The item I clicked on is added to the answerWidgetList (blue part). And removed from shuffleWidgetList (green part).
onTap: () {
setState(() {
shuffleWidgetList.remove(shuffleWordWidget(word));
//not necessary remove. Look at Problem 1.a
answerWidgetList.add(answerWordWidget(word));
answerWords.add(word);
});
},
2. Clicking on a word in the blue part adds it to its old place in the shuffleWidgetList(green part). And it is removed from answerWidgetList (blue part).
onTap: () {
setState(() {
shuffleWidgetList.add(shuffleWordWidget(word)); //Problem 1.b
answerWidgetList.remove(answerWordWidget(word)); //Problem 2
answerWords.remove(word);
});
},
Problems:
1.a. How can I change shuffleWordWidget's text color when I click an item in shuffleWidgetList?
I tried: In the shuffleWidgetList(green part) it is unnecessary to remove the item when clicking. Text should be transparent (to keep the widget size) and not be clicked again. For this I added bool clicked=false; to shuffleWordWidget. When clicked, onTap() updates to true, but color doesn't update. Like this:
shuffleWordWidget(String word) {
bool clicked = false;
return InkWell(
child: Container(
color: clicked == false ? Colors.white54 : Colors.grey,
child: Text(
word,
style: TextStyle(fontSize: 12,color:clicked == false ? Colors.black : Colors.transparent ),
),
),
onTap: () {
if (clicked == false) {
setState(() {
...
clicked = true;
});
}
},
);
}
1.b. How can I add shuffleWidgetList to its old place when an item is clicked in answerWidgetList?
For old place; that if the user clicks on a word from the answerWidgetList(blue part), it should be the same word clicked=false; again in the shuffleWidgetList(green part).
2. How can I remove item from answerWidgetList when I click an item in answerWidgetList?
answerWidgetList.remove(answerWordWidget(word)); doesn't work.
My approach may be completely wrong. You can also suggest different solutions.
Full code:
import 'package:collection/collection.dart';
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(
title: 'Sentence Creation',
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
static String mySentence = "My cat is black";
static List<String> correctWords = mySentence.split(" ");
static List<String> shuffleWords = [...correctWords]..shuffle();
List<String> answerWords = [];
List<Widget> shuffleWidgetList = [];
List<Widget> answerWidgetList = [];
generateShuffleWidgets() {
for (int i = 0; i < shuffleWords.length; i++) {
shuffleWidgetList.add(shuffleWordWidget(shuffleWords[i]));
}
}
#override
void initState() {
super.initState();
generateShuffleWidgets();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
flex: 2,
child: Container(
color: Colors.blue,
child: Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: answerWidgetList,
),
),
)),
Expanded(
child: Container(
color: Colors.green,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: shuffleWidgetList,
),
),
),
SizedBox(
height: 50,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
child: Center(child: Text("Check")),
onTap: () {
if (IterableEquality().equals(correctWords, answerWords)) {
print("correct");
} else {
print("wrong");
}
print("correct list: $correctWords");
print("answer list: $answerWords");
},
),
),
)
],
),
);
}
shuffleWordWidget(String word) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: InkWell(
child: Container(
color: Colors.white54,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
word,
style: TextStyle(fontSize: 12),
),
),
),
onTap: () {
setState(() {
shuffleWidgetList.remove(shuffleWordWidget(word));
//not necessary remove. Look at Problem 1.a
answerWidgetList.add(answerWordWidget(word));
answerWords.add(word);
});
},
),
);
}
answerWordWidget(String word) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: InkWell(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
word,
style: TextStyle(fontSize: 12),
),
),
),
onTap: () {
setState(() {
shuffleWidgetList.add(shuffleWordWidget(word)); //Problem 1.b
answerWidgetList.remove(answerWordWidget(word)); //Problem 2
answerWords.remove(word);
});
},
),
);
}
}
Put this code in _HomePageState.
static String mySentence = "My cat is black";
static List<String> correctWords = mySentence.split(" ");
static List<String> shuffleWords = [...correctWords]..shuffle();
List<String> answerWords = [];
List<Widget> shuffleWidgetList = [];
List<Widget> answerWidgetList = [];
generateShuffleWidgets() {
for (int i = 0; i < shuffleWords.length; i++) {
shuffleWidgetList.add(shuffleWordWidget(shuffleWords[i],true));
}
}
#override
void initState() {
super.initState();
generateShuffleWidgets();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
flex: 2,
child: Container(
color: Colors.blue,
child: Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: answerWidgetList,
),
),
)),
Expanded(
child: Container(
color: Colors.green,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: shuffleWidgetList,
),
),
),
SizedBox(
height: 50,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
child: Center(child: Text("Check")),
onTap: () {
if (IterableEquality().equals(correctWords, answerWords)) {
print("correct");
} else {
print("wrong");
}
print("correct list: $correctWords");
print("answer list: $answerWords");
},
),
),
)
],
),
);
}
shuffleWordWidget(String word,bool visible) {
return Visibility(
visible: visible,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: InkWell(
child: Container(
color: Colors.white54,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
word,
style: TextStyle(fontSize: 12),
),
),
),
onTap: () {
setState(() {
//shuffleWidgetList.remove(shuffleWordWidget(word));
int i = shuffleWords.indexOf(word);
shuffleWidgetList[i]=shuffleWordWidget(word,false);
//not necessary remove. Look at Problem 1.a
answerWidgetList.add(answerWordWidget(word));
answerWords.add(word);
});
},
),
),
);
}
answerWordWidget(String word) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: InkWell(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
word,
style: TextStyle(fontSize: 12),
),
),
),
onTap: () {
setState(() {
int i = shuffleWords.indexOf(word);
// shuffleWidgetList.insert(i,shuffleWordWidget(word)); //Problem 1.b
shuffleWidgetList[i]=shuffleWordWidget(word,true);
int y = answerWords.indexOf(word);
answerWidgetList.removeAt(y); //Problem 2
answerWords.remove(word);
});
},
),
);
}
I added a visibility detector which is triggered with a bool value. I used the shuffleWords list to get the index of the widget and hid it by changing the bool to false. Similarly answerWords can be used for removing widgets from answerWidgetList. As the widget from answerWidgetList is removed therefore we don't need visibility widget there.
Or if shuffleWordWidget is replaced with this then Visibility() is not needed and the image in the question is obtained.
shuffleWordWidget(String word, bool visible) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: InkWell(
child: Container(
color: visible == true ? Colors.white54 : Colors.grey,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
word,
style: TextStyle(
fontSize: 12,
color: visible == true ? Colors.black : Colors.transparent),
),
),
),
onTap: () {
if (visible == true) {
setState(() {
//shuffleWidgetList.remove(shuffleWordWidget(word));
int i = shuffleWords.indexOf(word);
shuffleWidgetList[i] = shuffleWordWidget(word, false);
//not necessary remove. Look at Problem 1.a
answerWidgetList.add(answerWordWidget(word));
answerWords.add(word);
});
}
},
),
);
}

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.

Dart, Flutter List onTap to get index of taped item

i created a search delegate class and what i want sounds logically simple but i cant wrap my head around it as i am new programming
i want to get the text or maybe i should say string of the text in the listTile i tap on ,
then pass that text to the showResult of search delegate and view it in a text widget
... here is my code
import 'package:flutter/material.dart';
import 'package:schooler/style/const.dart';
//follow steps 1 - 3
class DataSearch extends SearchDelegate<String> {
final List<String> languages = [//3.here is my list
'dart',
'Csharp',
'Java',
'JavaScript',
'C++',
'go ',
'python',
'php'
];
final List<String> recentSearch = [
'go ',
'python',
'php',
];
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = '';
},
)
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
},
);
}
#override
Widget buildResults(BuildContext context) {
return Scaffold(
body: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
Row(
children: <Widget>[
CircleAvatar(),
Text(languages[0].substring(query.length)),//2.i want to return the gotten index here
],
),
],
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
final suggestionList = query.isEmpty
? recentSearch
: languages.where((element) => element.startsWith(query)).toList();
return ListView.builder(
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) => ListTile(
onTap: () {
showResults(context); //1.when i tap the item on the listTile i want it to get the index of the taped item
},
leading: query.isEmpty
? Icon(
Icons.history,
)
: Icon(Icons.search),
title: RichText(
text: TextSpan(
text: suggestionList[index].substring(
0,
query.length,
),
style: TextStyle(
color: kBlackColor,
fontWeight: kBold,
),
children: [
TextSpan(
text: suggestionList[index].substring(query.length),
style: TextStyle(color: kGreyColor),
),
],
),
),
),
itemCount: suggestionList.length,
);
}
}
here if i tap on 'go' it should get get the text and pass it to the showResult
here is my show result ..but i just hard coded my 'list[0]index in there' i guess what i am trying to say is get the text from the item i taped and show it here
First lets fix your itemBuilder in your ListView so it indexes each element and then add that index into your showResults() function call so you have access to it:
ListView.builder(
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) => ListTile( // Add index here to pass the index to the builder.
onTap: () {
showResults(context, index); // Add the index to function call
},
Just be sure your showResults() function is modified to accept an int index parameter, and while I dont see that function, I am assuming it calls buildResults() at some point which needs to be modified to accept an index:
#override
Widget buildResults(BuildContext context, int index) {
return Scaffold(
body: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
Row(
children: <Widget>[
CircleAvatar(),
Text(languages[index].substring(query.length)),// Use the index here to return the desired text
],
),
],
),
);
}

How can i save my data in list that it can be used in entire lifecycle of application in flutter?

In my flutter application i am using mvp with clean architecture and my server return 5 items when it hit api, and when i scroll more it again hit api and get next 5 items. And i am saving these items in a list so that i can not call api again and again for already fetched items and this list was used in listview.builder. I had used bottom navigation bar and when i move from product items tab to any other tab and from there came to products items it again fetch products from api and thats not what i want. I want to show that list which was already fetched by that list in products list tab whenever i return back.
Video of my problem.
import 'dart:async';
import 'package:bakery_application/Bloc/TECartBloc.dart';
import 'package:bakery_application/Singleton/CartManager.dart';
import 'package:bakery_application/data/dataSource/product/remote/ProductRemoteDataSource.dart';
import 'package:bakery_application/data/model/responseDTO/ProductResponseDTO.dart';
import 'package:bakery_application/data/model/responseDTO/models/products.dart';
import 'package:bakery_application/data/model/responseDTO/models/productsList.dart';
import 'package:bakery_application/domain/repository/product/ProductRepo.dart';
import 'package:bakery_application/ui/productdetailscreeen/ProductDetailScreen.dart';
import 'package:bakery_application/ui/productscreen/IProductPresenter.dart';
import 'package:bakery_application/ui/productscreen/IProductView.dart';
import 'package:connectivity/connectivity.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:bakery_application/localmodels/ProductModel.dart';
import 'package:bakery_application/widgets/TEProductIncrementor.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:provider/provider.dart';
import 'ProductPresenter.dart';
class ProductScreen extends StatefulWidget {
Key key;
List<Products> myList = new List<Products>();
int _pageNumber = 1;
ProductScreen({
this.key,
}) : super(key: key);
#override
_ProductScreenState createState() => _ProductScreenState();
}
class _ProductScreenState extends State<ProductScreen> implements IProductView {
_ProductScreenState() {
productPresenter = ProductPresenter(
this,
ProductRepo(
ProductRemoteDataSource(),
),
);
}
bool circularindicator = false;
Color circularColor;
double circularOpacity;
IProductPresenter productPresenter;
AsyncSnapshot snapshotList;
var _connectionStatus = 'Unknown';
Connectivity connectivity;
StreamSubscription<ConnectivityResult> subscription;
ScrollController _scrollController = ScrollController();
bool cupertinoProgress;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.orange,
automaticallyImplyLeading: false,
title: Text(
'Product',
style: TextStyle(color: Colors.white),
),
),
body:
StreamBuilder(
stream: productPresenter.getProducts,
builder: (context, AsyncSnapshot<ProductsList> snapshot) {
if (snapshot.hasData) {
return productListView(widget.myList);
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
return Center(
child: Container(
child: CircularProgressIndicator(),
),
);
},
),
);
}
Future<Null> refreshList() async {
await Future.delayed(Duration(seconds: 2));
setState(() {});
return null;
}
Widget productListView(List snapshot) {
return RefreshIndicator(
onRefresh: refreshList,
child:
ListView.builder(
key: widget.key,
controller: _scrollController,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
if(index+1 == widget.myList.length) {
CupertinoActivityIndicator();
}
var plist = widget.myList[index];
return GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductDetailScreen(
product: plist,
),
),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: 120,
height: 130,
child: Image(
image: NetworkImage(plist.image),
),
),
Container(
child: Flexible(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
plist.name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
Text(
plist.description,
softWrap: true,
textAlign: TextAlign.left,
),
SizedBox(
height: 7,
),
Row(
children: <Widget>[
Text(plist.price.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
)),
Spacer(),
Text(plist.brand),
],
),
TEProductIncrementor(
product: plist,
),
//TODO reverse it alse
],
),
),
),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Divider(
color: Colors.grey.shade300,
),
),
],
)
],
),
),
);
},
itemCount: widget.myList.length,
),
);
}
productlist(BuildContext context, int index
}
#override
hideProgress(ProductsList response) {
setState(() {
// Here you can write your code for open new view
cupertinoProgress=false;
});
for (var c in response.products) {
widget.myList.add(c);
}
}
#override
showError(String error) {
// TODO: implement showError
return null;
}
#override
showProgress() {
print('Successful');
setState(() {
cupertinoProgress=true;
});
}
#override
void initState() {
super.initState();
connectivity = new Connectivity();
print('Init state called');
print('Init state called');
print('Init state called');
subscription =
connectivity.onConnectivityChanged.listen((ConnectivityResult result) {
_connectionStatus = result.toString();
print(_connectionStatus);
if (result == ConnectivityResult.wifi ||
result == ConnectivityResult.mobile) {
widget.myList.isEmpty
? productPresenter.fetchProducts(widget._pageNumber.toString())
:
widget._pageNumber = widget._pageNumber + 1;
productPresenter.fetchProducts(widget._pageNumber.toString(),);
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
widget._pageNumber = widget._pageNumber + 1;
print(widget._pageNumber);
productPresenter.fetchProducts(widget._pageNumber.toString(),);
}
});
} else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Center(
child: Container(
child: Icon(
Icons.add_alert,
color: Colors.orange,
size: 20,
),
),
),
content: Text('Check your internet'),
actions: <Widget>[
new FlatButton(
child: new Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
});
}
#override
void dispose() {
subscription.cancel();
super.dispose();
}
getMoreData() async {
}
}
The main problem you're facing is that each time the user scrolls of the tab you're in and returns to it, the app re-fetches the data again.
You can use IndexedStack to make the data only loads once, for that you can edit your code to be this way.
class BaseScreenState extends State<BaseScreen> {
List<Widget> _pages = [Page1(), Page2(), Page3()];
#override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: currentIndex,
children: _pages,
),
);
}
}