i am currently learning flutter and dart. I searched but couldn't find it.
I want to put a favorite button next to the names in the list and when clicked on it, I just want it to sort the favorites on the other page.
Here is my code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
AnaEkran createState() => AnaEkran();
}
class AnaEkran extends State<HomeScreen> {
static List<String> mainDataList = [
"Apple",
"Apricot",
"Banana",
"Blackberry",
"Coconut",
"Date",
"Fig",
"Gooseberry",
"Grapes",
"Lemon",
"Litchi",
"Mango",
"Orange",
"Papaya",
"Peach",
"Pineapple",
"Pomegranate",
"Starfruit"
];
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text('NickName Generator'),
backgroundColor: Colors.deepPurple,
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.article_rounded)),
Tab(icon: Icon(Icons.favorite)),
],
),
),
body: ListView.builder(
itemCount: mainDataList.length,
itemBuilder: (context, index) {
return Card (
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Text(mainDataList[index],style: TextStyle(fontSize: 19.0),),
),
);
},
),
),
);
}
}
And this is how it looks. The same list appears on the second page, but I only want the favorite words to be added there.
CodePudding user response:
Try this Code below Hope So it will Solve Your Problem
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
AnaEkran createState() => AnaEkran();
}
class AnaEkran extends State<HomeScreen> {
static List<String> mainDataList = [
"Apple",
"Apricot",
"Banana",
"Blackberry",
"Coconut",
"Date",
"Fig",
"Gooseberry",
"Grapes",
"Lemon",
"Litchi",
"Mango",
"Orange",
"Papaya",
"Peach",
"Pineapple",
"Pomegranate",
"Starfruit"
];
static List<String> favList = [
"Grapes",
"Lemon",
"Litchi",
"Mango",
"Orange",
];
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text('NickName Generator'),
backgroundColor: Colors.deepPurple,
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.article_rounded)),
Tab(icon: Icon(Icons.favorite)),
],
),
),
body: TabBarView(
children: [
ListView.builder(
itemCount: mainDataList.length,
itemBuilder: (context, index) {
return Card (
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Text(mainDataList[index],style: TextStyle(fontSize: 19.0),),
),
);
},
),
ListView.builder(
itemCount: favList.length,
itemBuilder: (context, index) {
return Card (
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Text(favList[index],style: TextStyle(fontSize: 19.0),),
),
);
},
),
],
)
),
);
}
}
CodePudding user response:
I'm gonna try to explain every required step, so bear with me.
First, you have to create a new list, which will be the list of favorite strings
List<String> mainDataList = [
"Apple",
"Apricot",
"Banana",
"Blackberry",
"Coconut",
"Date",
"Fig",
"Gooseberry",
"Grapes",
"Lemon",
"Litchi",
"Mango",
"Orange",
"Papaya",
"Peach",
"Pineapple",
"Pomegranate",
"Starfruit"
];
List<String> favoriteDataList = [];
Now, as the body for your Scaffold, you have to add a TabBarView widgets, which contains a List of Widgets. The amount of widgets in this list, has to match with the amount of tabs that you have added in the TabBar, since, whenever you tap one of the tabs in it, it will move to the TabBarView's widgets that matchs the index.
So the body for your Scaffold should look something like this:
TabBarView(
children: [
ListView.builder(
itemCount: mainDataList.length,
itemBuilder: (context, index) {
return Card(
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Text(
mainDataList[index],
style: const TextStyle(fontSize: 19.0),
),
),
),
ElevatedButton(
onPressed: () {
setState(() {
favoriteDataList.add(mainDataList[index]);
});
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
Colors.deepPurple,
),
),
child: const Icon(
Icons.favorite,
color: Colors.white,
),
),
],
),
);
},
),
favoriteDataList.isEmpty
? const Center(
child: Text(
'There are no favorites yet!',
style: TextStyle(color: Colors.black),
),
)
: ListView.builder(
itemCount: favoriteDataList.length,
itemBuilder: (context, index) {
return Card(
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Text(
favoriteDataList[index],
style: const TextStyle(fontSize: 19.0),
),
),
),
ElevatedButton(
onPressed: () {
setState(() {
favoriteDataList
.remove(favoriteDataList[index]);
});
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Colors.deepPurple,
),
),
child: const Icon(
Icons.remove,
color: Colors.white,
),
),
],
),
);
},
),
],
),
Of course, there is a lot of code there, I'm gonna split it in parts to explain it better. As you may see, first we have two Widgets inside the children of the TabBarView, first one is the one that you had, there are some differences, since I've added a Row and inside it, a ElevatedButton, which will take care of adding the desired element to the favorite list:
ElevatedButton(
onPressed: () {
setState(() {
favoriteDataList.add(mainDataList[index]);
});
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
Colors.deepPurple,
),
),
child: const Icon(
Icons.favorite,
color: Colors.white,
),
),
So, the important part of this button is the onPressed method, since you have built an StatefulWidget, we can tell that the state has been changed, using the setState method, it receives a function. Why do you need this? Because, you need a way to say the UI that the state has changed, so it has to rebuild. For example, in an StatelessWidget, you don't have the setState method, so you won't be able to update the UI, without using some specifics Widgets or some specific state management solution (like BLoC). Right now, when the user press this favorite button, we are going to add the selected item from the mainDataList to the favoriteDataList, making use of the index of the element that we have just pressed. And as I mentioned before, since the state was changed, the UI will rebuilt, so when you tap the favorite Tab, you will see that the selected item has been added.
The ElevatedButton in the second tab view, has some small differences
ElevatedButton(
onPressed: () {
setState(() {
favoriteDataList
.remove(favoriteDataList[index]);
});
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Colors.deepPurple,
),
),
child: const Icon(
Icons.remove,
color: Colors.white,
),
),
Apart from a different Icon, Instead of being adding elements, we want to remove them, so whenever we press the button, the item positioned in the same index, will be removed from the favoriteDataList.
I have also used a ternary operator to display a widget if the favoriteDataList is not:
favoriteDataList.isEmpty
? const Center(
child: Text(
'There are no favorites yet!',
style: TextStyle(color: Colors.black),
),
)
: ListView.builder(
If is empty we display the Center... and if is not, the ListView...
And that's pretty much all, of course there some improvements to do on this code, for example, if you tap the same item in the first tab more than once, it will be added to the favorite list multiple times. But I think the example works, and you will be able to play with it and fix it!
Sorry for the long post, I hope it helps!