Skip to content

Commit

Permalink
Arihant | remove tab bar from national dex
Browse files Browse the repository at this point in the history
  • Loading branch information
SatyamAK committed Jun 12, 2024
1 parent aa92280 commit 062f51c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 123 deletions.
64 changes: 28 additions & 36 deletions lib/components/app_bar_with_search.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'package:flutter/material.dart';
import 'package:pokedex_tracker/constants/color.dart';

class AppBarWithsearch extends StatefulWidget implements PreferredSizeWidget {
final Widget title;
final PreferredSizeWidget? bottom;
final Function(String value, BuildContext context) search;
const AppBarWithsearch({super.key, required this.title, this.bottom, required this.search}) :
preferredSize = (bottom != null)?const Size.fromHeight(84):const Size.fromHeight(52);
preferredSize = const Size.fromHeight(112);

@override
State<AppBarWithsearch> createState() => _AppBarWithsearchState();
Expand All @@ -15,52 +16,43 @@ class AppBarWithsearch extends StatefulWidget implements PreferredSizeWidget {
}

class _AppBarWithsearchState extends State<AppBarWithsearch> {
bool _isSearching = false;
final TextEditingController _textController = TextEditingController();

@override
AppBar build(BuildContext context) {
return AppBar(
title: (_isSearching)?searchBox():widget.title,
bottom: widget.bottom,
actions: [
IconButton(
onPressed: ()=>{
setState(() {
_isSearching = !_isSearching;
})
},
icon: Icon(
(_isSearching)?Icons.cancel_outlined:Icons.search
)
)
],
title: widget.title,
bottom: searchBox(),
);
}

Widget searchBox() {
return Container(
decoration: BoxDecoration(
color: const Color(0xffF5F5F5),
borderRadius: BorderRadius.circular(5)
),
child: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: TextField(
controller: _textController,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(
Icons.search_rounded,
color: Theme.of(context).primaryColorDark,
PreferredSizeWidget searchBox() {
return PreferredSize(
preferredSize: const Size.fromHeight(32),
child: Container(
margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 8.0),
decoration: BoxDecoration(
color: appBarTextColor,
borderRadius: BorderRadius.circular(24)
),
child: Padding(
padding: const EdgeInsets.only(left: 16.0),
child: TextField(
controller: _textController,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(
Icons.search_rounded,
color: Theme.of(context).primaryColorDark,
),
onPressed: () => FocusScope.of(context).unfocus(),
),
onPressed: () => FocusScope.of(context).unfocus(),
hintText: 'Search',
border: InputBorder.none,
),
hintText: 'Bulbasaur...',
border: InputBorder.none,
onChanged: (value) => widget.search(value, context),
onSubmitted: (value) => widget.search(value, context),
),
onChanged: (value) => widget.search(value, context),
onSubmitted: (value) => widget.search(value, context),
),
),
);
Expand Down
131 changes: 44 additions & 87 deletions lib/pages/national_dex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,106 +5,63 @@ import 'package:flutter/services.dart';
import 'package:pokedex_tracker/components/app_bar_with_search.dart';
import 'package:pokedex_tracker/components/pokemon_card.dart';
import 'package:pokedex_tracker/model/pokemon.dart';
import 'package:pokedex_tracker/provider/pokemon_provider.dart';
import 'package:provider/provider.dart';

class NationalDex extends StatefulWidget {
class NationalDex extends StatelessWidget {
final String selectedGeneration;
const NationalDex({required this.selectedGeneration, super.key});

@override
State<NationalDex> createState() => _NationalDexState();
}

class _NationalDexState extends State<NationalDex> with SingleTickerProviderStateMixin {
late TabController _tabController = _tabController = TabController(vsync: this, length: 0);
late Map<String, dynamic> _pokemonsGenerationWiseToBeRendered = <String, dynamic>{};
int _activeTabIndex = 0;
List<dynamic> _pokemonsTobeRendered = [];

void _loadPokemons() async {
Future<List<Pokemon>> _loadPokemons(BuildContext context) async {
late List<Pokemon> pokemons = [];
final String data = await rootBundle.loadString('data/pokedex.json');
final Map<String, dynamic> pokemonsGenerationWise = await jsonDecode(data);
final Map<String, dynamic> requiredPokemonsGenerationWise = <String, dynamic>{};
await Future.delayed(const Duration(seconds: 1));
for(var generation in pokemonsGenerationWise.keys) {
if(generation == widget.selectedGeneration) {
requiredPokemonsGenerationWise[generation] = pokemonsGenerationWise[generation];
break;
}
requiredPokemonsGenerationWise[generation] = pokemonsGenerationWise[generation];
final Map<String, dynamic> requiredPokemonGenerationWise = await jsonDecode(data);
for(var generation in requiredPokemonGenerationWise.keys) {
requiredPokemonGenerationWise[generation].forEach((pokemon) => pokemons.add(Pokemon.fromMap(pokemon)));
}
setState(() {
_pokemonsGenerationWiseToBeRendered = requiredPokemonsGenerationWise;
_tabController = TabController(vsync: this, length: requiredPokemonsGenerationWise.length);
_pokemonsTobeRendered = _pokemonsGenerationWiseToBeRendered['Generation 1'];
});
_tabController.addListener(() {
setState(() {
_activeTabIndex = _tabController.index;
var selectedGeneration = _pokemonsGenerationWiseToBeRendered.keys.elementAt(_activeTabIndex);
_pokemonsTobeRendered = _pokemonsGenerationWiseToBeRendered[selectedGeneration];
});
});
}

@override
void initState() {
_loadPokemons();
super.initState();
}

void filterPokemons(String value, BuildContext context) {
var selectedGeneration = _pokemonsGenerationWiseToBeRendered.keys.elementAt(_activeTabIndex);
if(value == "") {
setState(() {
_pokemonsTobeRendered = _pokemonsGenerationWiseToBeRendered[selectedGeneration];
});
if(!context.mounted) {
return pokemons;
}
setState(() {
_pokemonsTobeRendered = _pokemonsGenerationWiseToBeRendered[selectedGeneration].where(
(pokemon) => pokemon["name"].toString().toLowerCase().contains(value.toLowerCase())
).toList();
});

Provider.of<PokemonProvider>(context, listen: false).updatePokemons(pokemons);
return pokemons;
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarWithsearch(
title: const Text('National Dex'),
bottom: tabBar(),
search: filterPokemons,
),
body: body(),
);
}

PreferredSizeWidget tabBar() {
return PreferredSize(
preferredSize: const Size.fromHeight(32),
child: (_pokemonsGenerationWiseToBeRendered.isEmpty)?const SizedBox():TabBar(
isScrollable: true,
tabAlignment: TabAlignment.start,
controller: _tabController,
tabs: _pokemonsGenerationWiseToBeRendered.keys.map((generation) => Tab(child: Text(generation),)).toList()
)
);
}

Widget body() {
return (_pokemonsGenerationWiseToBeRendered.isEmpty)?const Center( child: CircularProgressIndicator()):TabBarView(
controller: _tabController,
children: _pokemonsGenerationWiseToBeRendered.keys.map(
(generation) {
return pokemonsView();
return FutureBuilder(
future: _loadPokemons(context),
builder: (context, snapshot) {
List<Pokemon> pokemonsFromSnapshot(){
if(snapshot.hasData) return snapshot.data!;
return [];
}
).toList()
);
}

Widget pokemonsView() {
return ListView.builder(
itemCount: _pokemonsTobeRendered.length,
itemBuilder: (context, index) => PokemonCard(pokemon: Pokemon.fromMap(_pokemonsTobeRendered.elementAt(index)))
void filterPokemons(String value, BuildContext context) {
if(value == "") {
Provider.of<PokemonProvider>(context, listen: false).updatePokemons(pokemonsFromSnapshot());
}
Provider.of<PokemonProvider>(context, listen: false).updatePokemons(
pokemonsFromSnapshot().where(
(pokemon) => pokemon.name.toLowerCase().contains(value.toLowerCase())
).toList()
);
}
return Scaffold(
appBar: AppBarWithsearch(
title: const Text('National Dex'),
search: filterPokemons,
),
body: (!snapshot.hasData)?const Center(child: CircularProgressIndicator(),):Consumer<PokemonProvider>(
builder: (context, pokemonProvider, child) {
return ListView.builder(
itemCount: pokemonProvider.pokemons.length,
itemBuilder: (context, index) => PokemonCard(pokemon: pokemonProvider.pokemons.elementAt(index))
);
}
)
);
}
);
}
}

0 comments on commit 062f51c

Please sign in to comment.