rsflutterapp

Bahnhofsfoto-App for Android and iOS using Flutter
git clone git://archive.git.mtrnord.blog/MTRNord/rsflutterapp.git
Log | Files | Refs | README

commit 21e3f38a70ff5c97e1ac51520b8bcfd36dd8391e
parent 7b2220109b020f42e36e6f9e15eacaeadad30c1f
Author: Marcel <mtrnord1@gmail.com>
Date:   Sat, 29 Feb 2020 21:54:44 +0100

Add Search to RankingsTab

Took 15 minutes

Diffstat:
Mlib/views/HomePage.dart | 9++-------
Mlib/views/tabs/RankingsTab.dart | 220++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mlib/views/tabs/StationsTab.dart | 4++--
3 files changed, 145 insertions(+), 88 deletions(-)

diff --git a/lib/views/HomePage.dart b/lib/views/HomePage.dart @@ -78,13 +78,8 @@ class HomePage extends StatelessWidget { ), ), ), - Scaffold( - appBar: AppBar( - title: Text("Rangliste"), - ), - body: RankingsTab( - railwayStationsRepository: railwayStationsRepository, - ), + RankingsTab( + railwayStationsRepository: railwayStationsRepository, ), StationsTab( railwayStationsRepository: railwayStationsRepository, diff --git a/lib/views/tabs/RankingsTab.dart b/lib/views/tabs/RankingsTab.dart @@ -1,6 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:rs_flutter_app/components/SearchBar.dart'; import '../../repos/repositories.dart'; @@ -16,100 +17,161 @@ class RankingsTab extends StatefulWidget { class RankingsTabState extends State<RankingsTab> with AutomaticKeepAliveClientMixin<RankingsTab> { + final filterTextController = TextEditingController(); List<List<String>> scores; + String filterText; + + List<List<String>> filter() { + var scoresL = scores; + if (filterText != null && filterText != "") { + scoresL = scores + .where( + (score) => (filterText != null && + filterText != "" && + score[1].toLowerCase().contains(filterText.toLowerCase())), + ) + .toList(growable: false); + } + return scoresL; + } Future<List<List<String>>> getScores() async { if (scores == null) { - scores = await widget.railwayStationsRepository.getScores(); + List<List<String>> scoresL = + await widget.railwayStationsRepository.getScores(); + + scoresL.removeAt(0); + scoresL.sort( + (a, b) => (int.parse(b.first)).compareTo(int.parse(a.first)), + ); + scores = scoresL; } return scores; } + void handleFilter() { + setState(() { + filterText = filterTextController.text; + }); + } + + @override + initState() { + super.initState(); + filterTextController.addListener(handleFilter); + } + + @override + void dispose() { + filterTextController.removeListener(handleFilter); + super.dispose(); + } + @override Widget build(BuildContext context) { super.build(context); - return FutureBuilder( - future: getScores(), - builder: - (BuildContext context, AsyncSnapshot<List<List<String>>> snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.done: - if (snapshot.hasError) { - // TODO handle error - debugPrint(snapshot.error.toString()); - } - if (snapshot.hasData) { - List<List<String>> scores = snapshot.data; - scores.removeAt(0); - scores.sort( - (a, b) => (int.parse(b.first)).compareTo(int.parse(a.first)), - ); - - return ListView.separated( - itemCount: scores.length, - separatorBuilder: (BuildContext context, int index) { - return Divider(); - }, - itemBuilder: (BuildContext context, int index) { - if (index == 0) { - return ListTile( - leading: SvgPicture.asset( - "assets/crown_gold.svg", - semanticsLabel: 'Golden Crown', - width: 50, - height: 50, - ), - title: Text(scores[index][1]), - ); - } else if (index == 1) { - return ListTile( - leading: SvgPicture.asset( - "assets/crown_silver.svg", - semanticsLabel: 'Silver Crown', - width: 50, - height: 50, - ), - title: Text(scores[index][1]), - ); - } else if (index == 2) { - return ListTile( - leading: SvgPicture.asset( - "assets/crown_bronze.svg", - semanticsLabel: 'Bronze Crown', - width: 50, - height: 50, - ), - title: Text(scores[index][1]), - ); - } else { - return ListTile( - leading: SizedBox( - width: 50, - height: 50, - child: Center( - child: Text( - "${(index + 1)}.", - style: TextStyle( - fontWeight: FontWeight.bold, - ), - ), - ), - ), - title: Text(scores[index][1]), - ); - } - }, - ); - } - // TODO handle missing date - return Container(); - default: + return Scaffold( + appBar: AppBar( + title: Text("Rangliste"), + bottom: PreferredSize( + preferredSize: Size.fromHeight(56), + child: Padding( + padding: EdgeInsets.all(8), + child: SearchBar( + filterTextController: filterTextController, + ), + ), + ), + ), + body: FutureBuilder( + future: getScores(), + builder: + (BuildContext context, AsyncSnapshot<List<List<String>>> snapshot) { + if (snapshot.hasError) { + // TODO handle error + debugPrint(snapshot.error.toString()); + } + + if (!snapshot.hasData) { return Center( child: CircularProgressIndicator(), ); - } - }, + } + + var filtered = filter(); + + if (filtered == null || filtered.isEmpty) { + return Container(); + } + + if (scores.isEmpty) { + return Container(); + } + + return ListView.separated( + itemCount: filtered.length, + separatorBuilder: (BuildContext context, int index) { + return Divider(); + }, + itemBuilder: (BuildContext context, int index) { + if (scores + .indexWhere((score) => score[1] == filtered[index][1]) == + 0) { + return ListTile( + leading: SvgPicture.asset( + "assets/crown_gold.svg", + semanticsLabel: 'Golden Crown', + width: 50, + height: 50, + ), + title: Text(filtered[index][1]), + ); + } else if (scores + .indexWhere((score) => score[1] == filtered[index][1]) == + 1) { + return ListTile( + leading: SvgPicture.asset( + "assets/crown_silver.svg", + semanticsLabel: 'Silver Crown', + width: 50, + height: 50, + ), + title: Text(filtered[index][1]), + ); + } else if (scores + .indexWhere((score) => score[1] == filtered[index][1]) == + 2) { + return ListTile( + leading: SvgPicture.asset( + "assets/crown_bronze.svg", + semanticsLabel: 'Bronze Crown', + width: 50, + height: 50, + ), + title: Text(filtered[index][1]), + ); + } else { + return ListTile( + leading: SizedBox( + width: 50, + height: 50, + child: Center( + child: Text( + "${(scores.indexWhere((score) => score[1] == filtered[index][1]) + 1)}.", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ), + ), + title: Text(filtered[index][1]), + ); + } + }, + ); + }, + ), ); } diff --git a/lib/views/tabs/StationsTab.dart b/lib/views/tabs/StationsTab.dart @@ -56,7 +56,7 @@ class StationsTabState extends State<StationsTab> super.dispose(); } - Future<List<Station>> getStations(String filterText) async { + Future<List<Station>> getStations() async { if (stations == null) { List<Station> stationsL = await widget.railwayStationsRepository.getStations(); @@ -86,7 +86,7 @@ class StationsTabState extends State<StationsTab> ), ), body: FutureBuilder<List<Station>>( - future: getStations(filterText), + future: getStations(), builder: (BuildContext context, AsyncSnapshot<List<Station>> snapshot) { if (snapshot.hasError) { // TODO handle error