Reputation: 463
I have a JSON file like this (API)
[
{
"language": "English",
"bySpeakers": 1121,
"inCountry": 59,
"onInternet": 0.04
},
{
"language": "French",
"bySpeakers": 284.9,
"inCountry": 29,
"onInternet": 0.02
},
{
"language": "Spanish",
"bySpeakers": 512.9,
"inCountry": 21,
"onInternet": 0.01
},
{
"language": "Arabic",
"bySpeakers": 422,
"inCountry": 26,
"onInternet": 0.053
},
{
"language": "Portuguse",
"bySpeakers": 236.5,
"inCountry": 9,
"onInternet": 0.01
}
]
I want that when I click on the DropdownButton
then select each button => the list will be sorted as follows:
bySpeakers
order
(descending)inCountry
order
(descending)onInternet
order
(descending)So pls help me, this is the main file:
import 'package:ask/model/sort_model.dart';
import 'package:ask/services/sort_service.dart';
import 'package:flutter/material.dart';
class SortPage extends StatefulWidget {
@override
_SortPageState createState() => _SortPageState();
}
class _SortPageState extends State<SortPage> {
List<Sort> _sort = [];
List<String> dropDown = <String>["Default", "Alphabet", "By Speakers", "In Countries", "On Internet"];
@override
void initState() {
super.initState();
SortServices.getData().then((data) {
setState(() {
_sort = data;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Sort'),
new DropdownButton<String>(
underline: Container(),
icon: Icon(Icons.sort,color: Colors.white),
items: dropDown.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String value) {
setState(() {});
})
],
)),
body: Column(
children: [
Container(
color: Colors.grey,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [Text('Language'), Text('By Speakers'), Text('In Countries'), Text('On Internet')],
),
),
for (Sort s in _sort)
Row(children: [
Expanded(child: Text(s.language)),
Expanded(child: Text('${s.bySpeakers} billion')),
Expanded(child: Text('${s.inCountry} countries')),
Expanded(child: Text('${s.onInternet * 100} %')),
])
],
));
}
}
Upvotes: 0
Views: 5115
Reputation: 1
import 'package:ask/model/sort_model.dart';
import 'package:ask/services/sort_service.dart';
import 'package:flutter/material.dart';
class SortPage extends StatefulWidget {
@override
_SortPageState createState() => _SortPageState();
}
class _SortPageState extends State<SortPage> {
List<Sort> _sort = [];
List<String> dropDown = <String>["Default", "Alphabet", "By Speakers", "In Countries", "On Internet"];
@override
void initState() {
super.initState();
SortServices.getData().then((data) {
setState(() {
_sort = data;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Sort'),
new DropdownButton<String>(
underline: Container(),
icon: Icon(Icons.sort,color: Colors.white),
items: dropDown.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList()..sort((a, b) => b.value!.compareTo(a.value!)),
onChanged: (String value) {
setState(() {});
})
],
)),
body: Column(
children: [
Container(
color: Colors.grey,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [Text('Language'), Text('By Speakers'), Text('In Countries'), Text('On Internet')],
),
),
for (Sort s in _sort)
Row(children: [
Expanded(child: Text(s.language)),
Expanded(child: Text('${s.bySpeakers} billion')),
Expanded(child: Text('${s.inCountry} countries')),
Expanded(child: Text('${s.onInternet * 100} %')),
])
],
));
}
}
Upvotes: 0
Reputation: 36
In Dart, the List
type has a sort
function which lets you sort the list. You give the sort
function another function that compares between any two objects in the list. It returns an integer that represents whether an object is less than, equal to or larger than the other object. If the returned value is -1
(might work for all negative numbers but I'm not sure), this means that the first object is less that the second object. If it's 0
, they're equal, and if it's 1
(again, might work for all positives but not sure) the first object is larger than the second.
I assume your Sort
class is defined as follows:
class Sort{
String language;
double bySpeakers, inCountries, onInternet;
}
To sort the list _sort
alphabetically, your sort call will look something like this:
_sort.sort((first, second) => first.language.compareTo(second.language));
Note that this function call will change the list itself. If you want to keep your original list, make sure you're sorting a copy of the list. A soft copy (only copy references to a new array) can be achieved using map
like this:
List<Sort> copy = _sort.map((e) => e).toList();
I'll give one more sort example for the bySpeakers
field:
// Sort the list using the bySpeakers attribute
_sort.sort((first, second){
if(first.bySpeakers > second.bySpeakers)
return 1;
else if(first.bySpeakers < second.bySpeakers)
return -1;
else
return 0;
});
Note that sort
sorts in ascending order. To make it descending, you can swap between return 1;
and return -1;
, or use the getter reversed
on the list, which will return an Iterable
containing the reversed list.
So define a function that does the sorting:
// function defined in the state class
void sortItems(String value){
// assuming the original list is stored _originalList
_sort = _originalList.map((e)=>e).toList();
switch(value){
case 'Alphabet':
_sort.sort((first, second)=>first.language.comprateTo(second.language));
break;
case 'By Speakers':
_sort.sort((first, second){
if(first.bySpeakers > second.bySpeakers)
return -1; // reversed
else if(first.bySpeakers < second.bySpeakers)
return 1; // reversed
else
return 0;
});
break;
case 'In Countries':
_sort.sort((first, second){
if(first.inCountries > second.inCountries)
return -1; // reversed
else if(first.inCountries < second.inCountries)
return 1; // reversed
else
return 0;
});
break;
case 'On Internet':
_sort.sort((first, second){
if(first.onInternet > second.onInternet)
return -1; // reversed
else if(first.onInternet < second.onInternet)
return 1; // reversed
else
return 0;
});
break;
default:
break;
}
}
Now you will need to call this function inside the onChanged
function for the DropdownButton
, something like this:
onChanged: (String value) {
setState(() {
sortItems(value);
});
})
Upvotes: 2