StationsTab.dart (3883B)
1 import 'package:flutter/cupertino.dart'; 2 import 'package:flutter/material.dart'; 3 import 'package:rs_flutter_app/components/SearchBar.dart'; 4 5 import '../../models/models.dart'; 6 import '../../repos/repositories.dart'; 7 import '../DetailsPage.dart'; 8 9 class StationsTab extends StatefulWidget { 10 final RailwayStationsRepository railwayStationsRepository; 11 12 StationsTab({@required this.railwayStationsRepository}) 13 : assert(railwayStationsRepository != null); 14 15 @override 16 StationsTabState createState() => StationsTabState(); 17 } 18 19 class StationsTabState extends State<StationsTab> 20 with AutomaticKeepAliveClientMixin<StationsTab> { 21 final filterTextController = TextEditingController(); 22 List<Station> stations; 23 String filterText; 24 25 List<Station> filter() { 26 var stationsL = stations; 27 if (filterText != null && filterText != "") { 28 stationsL = stations 29 .where( 30 (station) => (filterText != null && 31 filterText != "" && 32 station.title 33 .toLowerCase() 34 .startsWith(filterText.toLowerCase())), 35 ) 36 .toList(growable: false); 37 } 38 return stationsL; 39 } 40 41 void handleFilter() { 42 setState(() { 43 filterText = filterTextController.text; 44 }); 45 } 46 47 @override 48 initState() { 49 super.initState(); 50 filterTextController.addListener(handleFilter); 51 } 52 53 @override 54 void dispose() { 55 filterTextController.removeListener(handleFilter); 56 super.dispose(); 57 } 58 59 Future<List<Station>> getStations() async { 60 if (stations == null) { 61 List<Station> stationsL = 62 await widget.railwayStationsRepository.getStations(); 63 stationsL.sort( 64 (a, b) => (a.title).compareTo(b.title), 65 ); 66 stations = stationsL; 67 } 68 return stations; 69 } 70 71 @override 72 Widget build(BuildContext context) { 73 super.build(context); 74 75 return Scaffold( 76 appBar: AppBar( 77 title: Text("Bahnhöfe"), 78 bottom: PreferredSize( 79 preferredSize: Size.fromHeight(56), 80 child: Padding( 81 padding: EdgeInsets.all(8), 82 child: SearchBar( 83 filterTextController: filterTextController, 84 ), 85 ), 86 ), 87 ), 88 body: FutureBuilder<List<Station>>( 89 future: getStations(), 90 builder: (BuildContext context, AsyncSnapshot<List<Station>> snapshot) { 91 if (snapshot.hasError) { 92 // TODO handle error 93 debugPrint(snapshot.error.toString()); 94 } 95 if (!snapshot.hasData) { 96 return Center( 97 child: CircularProgressIndicator(), 98 ); 99 } 100 var filtered = filter(); 101 102 if (filtered == null || filtered.isEmpty) { 103 return Container(); 104 } 105 106 if (stations.isEmpty) { 107 return Container(); 108 } 109 110 return ListView.separated( 111 itemCount: filtered.length, 112 separatorBuilder: (BuildContext context, int index) { 113 return Divider(); 114 }, 115 itemBuilder: (BuildContext context, int index) { 116 return ListTile( 117 trailing: 118 filtered[index].photoUrl != "" ? Icon(Icons.image) : null, 119 title: Text(filtered[index].title), 120 onTap: () { 121 Navigator.of(context).push( 122 MaterialPageRoute( 123 builder: (BuildContext context) => DetailsPage( 124 station: filtered[index], 125 railwayStationsRepository: 126 widget.railwayStationsRepository, 127 ), 128 ), 129 ); 130 }, 131 ); 132 }, 133 ); 134 }, 135 ), 136 ); 137 } 138 139 @override 140 bool get wantKeepAlive => true; 141 }