Im making a Flutter app that shows a list of items, and I would like to filter this list based on a String in a search bar. I have Riverpod to provide a String that will be used in the filter. Base on this String I would like to change the suffixIcon
when the String is not empty.
I only able to update only one or the other (text in search bar or the icon) together they don’t work.
What is going on?
final searchProvider = StateProvider<String>((ref) => '');
class OverviewScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final houseDataValue = ref.watch(listHousesProvider);
final searchController = TextEditingController();
return Column(
children: [
Padding(
padding: EdgeInsets.only(top: 0.75.h, bottom: 1.5.h, right: 4.2.w, left: 4.2.w),
child: Container(
decoration: BoxDecoration(
color: AppColors.darkGray,
borderRadius: BorderRadius.circular(8.0),
),
child: Padding(
padding: EdgeInsets.only(left: 4.w, top: 0.4.h),
child: TextField(
controller: searchController,
cursorColor: AppColors.medium,
style: AppTypography.input,
decoration: InputDecoration(
hintText: 'Search for a home',
hintStyle: AppTypography.hint,
suffixIcon: IconButton(
icon: ref.watch(searchProvider).isNotEmpty // ICON DOES NOT UPDATE
? Icon(Icons.ac_unit_outlined)
: Icon(Icons.access_alarm_outlined),
onPressed: () {},
),
border: InputBorder.none,
),
onChanged: (value) {
// OR THE TEXT INSIDE THE SEARCH BAR
ref.read(searchProvider.notifier).update((state) => state = value);
},
),
),
),
),
],
);
}
}
2
Answers
You need to declare TextEditingController outside the build method. It’s getting reassigned empty string on input changed.
I would suggest to check
ConsumerStatefulWidget
.In fact, you need to make another provider that would only control the empty string. Try this:
Now your ui looks like this:
I specifically used
Consumer
to show that only the icon will be rebuilt, and not the entireOverviewScreen
widget.Also note that you should create ANY controllers, text, focus, scroll, etc., only inside
initState
, and dispose of them insidedispose
. This will help prevent memory leaks.