I am trying to build a dictionary app. My homepage, which is returned from the main file, is supposed to have the words. I want to implement go router in the home screen which is called DictionaryScreenEnglish, and by tapping the words I want go router to push to the entry pages. I am unable to implement the onTap functionality when the words are tapped. Below is the code of my DictionaryScreenEnglish
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:zeetionary/dictionary/english_dictionary/alphabet/letter_a/letters_ab/en_entry_aback.dart'; // a page that contains the entry for the word "aback"
final GoRouter _router = GoRouter(
routes: <RouteBase>[
GoRoute(
path: '/dictionaryenglish',
builder: (BuildContext context, GoRouterState state) {
return const DictionaryScreenEnglish();
},
routes: <RouteBase>[
GoRoute(
path: 'english/:aback',
builder: (BuildContext context, GoRouterState state) {
return EnglishEntryAback();
},
),
],
),
],
);
class DictionaryScreenEnglish extends StatefulWidget {
const DictionaryScreenEnglish({Key? key}) : super(key: key);
@override
State<DictionaryScreenEnglish> createState() =>
_DictionaryScreenEnglishState();
}
class _DictionaryScreenEnglishState extends State<DictionaryScreenEnglish> {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
final List<String> allWordsEnglish = [
"aback",
"abacus",
];
List<String> filteredWords = [];
final TextEditingController _searchController = TextEditingController();
@override
void initState() {
super.initState();
filteredWords = List.from(allWordsEnglish);
}
void filterWords(String query) {
setState(() {
filteredWords = allWordsEnglish
.where((word) => word.toLowerCase().contains(query.toLowerCase()))
.toList();
});
}
void clearSearch() {
_searchController.clear();
filterWords('');
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Directionality(
textDirection: TextDirection.ltr,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: SizedBox(
height: 60,
child: TextField(
controller: _searchController,
onChanged: filterWords,
decoration: InputDecoration(
labelText: 'Search here',
prefixIcon: const Icon(Icons.search),
suffixIcon: IconButton(
icon: const Icon(Icons.clear),
onPressed: clearSearch,
),
border: const OutlineInputBorder(),
),
),
),
),
),
Expanded(
child: Directionality(
textDirection: TextDirection.ltr,
child: EnglishDictionary(
words: filteredWords,
onTapWord: (wordsEnglish) {
if (wordsEnglish == "aback") {
context.go('english/:aback');
}
},
),
),
),
],
),
);
}
@override
void dispose() {
_searchController.dispose();
super.dispose();
}
}
class EnglishDictionary extends StatelessWidget {
final List<String> words;
final Function(String) onTapWord;
const EnglishDictionary({
Key? key,
required this.words,
required this.onTapWord,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: words.length,
itemBuilder: (BuildContext context, int index) {
return ListTileEnglish(
wordsEnglish: words[index],
onTap: () {
onTapWord(words[index]);
},
);
},
);
}
}
class ListTileEnglish extends StatelessWidget {
final String wordsEnglish;
final VoidCallback? onTap;
const ListTileEnglish({
Key? key,
required this.wordsEnglish,
this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: ListTile(
key: key,
title: Text(wordsEnglish),
trailing: const Icon(Icons.arrow_forward),
),
);
}
}
class CardButton extends StatelessWidget {
final String label;
final VoidCallback? onPressed;
const CardButton({
Key? key,
required this.label,
this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
height: 50,
child: Card(
child: InkWell(
onTap: onPressed,
child: Center(
child: Text(
label,
style: const TextStyle(fontSize: 16),
),
),
),
),
);
}
}
2
Answers
One possible issue is that you haven’t configured your MaterialApp.router().
The other issue is that you have a nested navigation and you want to navigate to english/:aback, which is not a path in your goRouter. If you want to navigate to the correct path with go() you need to specify the whole path to it like this:
Change your GoRouter to accept the pathParameter:
I think maybe the
onTap
is not being triggered to begin with. Try updating theListTileEnglish
‘s andCarButton
‘s onTap` handler invocation to something like: