I would like to sort a ListView based on a StreamController in a BottomNavigationBar. The problem is that the Listview doesn't refresh when I click the button on the app bar.
I would like to pass as parameter the function (Comparable of Company) which the user chooses.
Here's my code:
Home.dart
final CompanyService _companyService = CompanyService();
final AuthService _auth = AuthService();
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
Home createState() => Home();
}
class Home extends State<HomePage> {
Comparator<Company> _sortFunction;
int _currentIndex;
var _tabs = [];
@override
void initState() {
super.initState();
_currentIndex = 0;
_sortFunction = (a, b) => a.name.compareTo(b.name);
}
PreferredSize getDoubleHomeAppBar() {
return PreferredSize(
preferredSize: Size.fromHeight(55.0),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.only(left: 12.0),
margin:
const EdgeInsets.only(left: 12.0, bottom: 8.0, right: 12.0),
color: PRIMARY_COLOR,
),
),
FlatButton.icon(
icon: Icon(Icons.sort_by_alpha),
label: Text(
'Sort',
),
onPressed: () {
setState(() {
_sortFunction = (a, b) => b.city.compareTo(a.city);
_tabs[0] = CompanyTab(sortFunction: _sortFunction);
});
},
),
],
));
}
@override
Widget build(BuildContext context) {
_tabs = [
CompanyTab(sortFunction: _sortFunction),
MapTab(),
Center(child: Text('Profile')),
Center(child: Text('Settings')),
];
return Scaffold(
backgroundColor: BACKGROUND_COLOR,
appBar: AppBar(
elevation: 0.0,
centerTitle: true,
title: Text(
'JobAdvisor',
style: TextStyle(
fontSize: MediaQuery.of(context).size.height / 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
bottom: _currentIndex == 0 ? getDoubleHomeAppBar() : null,
actions: <Widget>[...],
),
body: _tabs[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
backgroundColor: BACKGROUND_COLOR,
type: BottomNavigationBarType.fixed,
items: [
...
],
onTap: (index) {
setState(() {
_currentIndex = index;
print('Index: $index');
print('Current index: $_currentIndex');
});
},
),
);
}
}
CompanyTab.dart
@immutable
class CompanyTab extends StatefulWidget {
final CompanyService _companyService = CompanyService();
final Comparator<Company> sortFunction;
CompanyTab({Key key, this.sortFunction}) : super(key: key);
@override
_CompanyTabState createState() =>
_CompanyTabState(_companyService, sortFunction);
}
class _CompanyTabState extends State<CompanyTab> {
StreamController<List<Company>> _streamController;
final CompanyService _companyService;
Comparator<Company> sortFunction;
_CompanyTabState(this._companyService, this.sortFunction);
@override
void initState() {
super.initState();
}
StreamBuilder companyList() {
return StreamBuilder<List<Company>>(
initialData: [],
stream: _streamController.stream,
builder: (BuildContext context, AsyncSnapshot<List<Company>> snapshot) {
if (snapshot.hasError) {
return Text("Something went wrong");
}
if (snapshot.connectionState == ConnectionState.waiting ||
snapshot.connectionState == ConnectionState.none ||
snapshot.data == null) {
return LoadingWidget();
} else {
return ListView.builder(
padding: const EdgeInsets.all(10),
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Company company = snapshot.data.elementAt(index);
...
}
}
});
}
@override
void dispose() {
_streamController.close();
super.dispose();
}
void _getData() {
_streamController = new StreamController<List<Company>>();
_companyService.getCompanies().then((value) => {_elaborateList(value)});
}
void _elaborateList(List<Company> list) {
List<Company> tmp = list;
tmp.sort(sortFunction);
print(tmp.toString());
_streamController.sink.add(tmp);
}
@override
Widget build(BuildContext context) {
_getData();
return Center(
child: Container(
child: companyList(),
),
);
}
}
I think the problem is in your sort method. It should be like this:
You can read from the official document.
EDIT:
And you need to use sortFunction of the widget in here:
You are not using the same sortFunction in CompanyTab. You should use the sortFunction which comes as a parameter. Here is a blog about it.