Reputation: 33
I'm using Riverpod with StateProvider for my app.
The home page will change based on tabs clicked.
When i click the ListTile tab to trigger the ref.read, it rebuild super fast:
But when i click the leading IconButton in Appbar which trigger ref.read(countProvider.notifier).state = 0;
it takes me fews seconds to reload the back to 0. How do i fix this?
Full code:
layout.dart:
Set<Widget> _pages = {
const HomeUI(),
const FAQ(),
const Setting(),
};
class Layout extends ConsumerStatefulWidget {
const Layout({super.key});
@override
LayoutState createState() => LayoutState();
}
class LayoutState extends ConsumerState<Layout> {
bool isHome = true;
@override
Widget build(BuildContext context) {
final tab = ref.watch(countProvider);
if (tab != 0) {
isHome = false;
} else {
isHome = true;
}
return Scaffold(
drawer: const Sidebar(),
appBar: isHome
? AppBar(
leading: Builder(builder: (context) {
return IconButton(
icon: const Icon(FontAwesomeIcons.bars),
color: CustomColors.mainText,
onPressed: () {
Scaffold.of(context).openDrawer();
},
);
}),
actions: [
Padding(
padding: const EdgeInsets.only(right: 20),
child: IconButton(
icon: const Icon(FontAwesomeIcons.magnifyingGlass),
color: CustomColors.mainText,
onPressed: () {},
),
),
],
backgroundColor: Colors.transparent,
)
: null,
backgroundColor: CustomColors.background,
body: Stack(children: <Widget>[
_pages.elementAt(tab),
const MiniPlayer(),
]),
);
}
}
faq_screen.dart
class FAQ extends StatelessWidget {
const FAQ({super.key});
@override
Widget build(BuildContext context) {
return Consumer(
builder: (context, ref, child) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
ref.read(countProvider.notifier).state = 0;
},
),
title: const Text('FAQ'),
),
body: const Center(
child: Text('FAQ'),
),
);
},
);
}
}
sidebar.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../utilities/color.dart';
import '../utilities/provider.dart';
class Sidebar extends StatelessWidget {
const Sidebar({super.key});
@override
Widget build(BuildContext context) {
return Drawer(
backgroundColor: CustomColors.background,
child: Consumer(
builder: (context, ref, child) => ListView(
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
accountName: const Text("Wolhaiksong",
style: TextStyle(
color: Colors.white,
fontFamily: 'Gilroy',
fontWeight: CustomColors.semiBold)),
accountEmail: const Text("[email protected]",
style: TextStyle(
color: Colors.white,
fontFamily: 'Gilroy',
fontWeight: CustomColors.regular)),
currentAccountPicture: CircleAvatar(
child: ClipOval(
child: Image.asset('assets/user.jpg'),
),
),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/wallpaper.jpg'),
fit: BoxFit.cover),
),
),
ListTile(
leading: const Icon(
FontAwesomeIcons.lightbulb,
color: CustomColors.gray,
),
title: const Padding(
padding: EdgeInsets.all(15.0),
child: Text('FAQs',
style: TextStyle(
color: CustomColors.mainText,
fontWeight: CustomColors.semiBold,
fontFamily: 'Gilroy',
)),
),
onTap: () {
ref.read(countProvider.notifier).state = 1;
Navigator.pop(context);
},
),
ListTile(
leading: const Icon(
FontAwesomeIcons.gear,
color: CustomColors.gray,
),
title: const Padding(
padding: EdgeInsets.all(15.0),
child: Text('Settings',
style: TextStyle(
color: CustomColors.mainText,
fontWeight: CustomColors.semiBold,
fontFamily: 'Gilroy',
)),
),
onTap: () {
ref.read(countProvider.notifier).state = 2;
Navigator.pop(context);
},
),
],
),
),
);
}
}
provider.dart
final countProvider = StateProvider<int>((ref) {
return 0;
});
Upvotes: 3
Views: 231
Reputation: 33
I'm sorry guys, turns out the problem is not Riverpod but the async function i used to extract dominant color from the image.
static Future<Color> generatePaletteColor(url) async {
final PaletteGenerator paletteGenerator =
await PaletteGenerator.fromImageProvider(
AssetImage(url),
);
return paletteGenerator.paletteColors[0].color;
}
And I use it in initState so it runs everytime countProvider change
@override
void initState() {
super.initState();
CustomColors.generatePaletteColor(widget.song.artWork).then((value) {
if (mounted) {
setState(() {
glowColor = value;
});
}
});
}
Is there anyway to move the async function outside of this or prevent initState
from rerun everytime rebuilt?
Upvotes: 0
Reputation: 4844
Since you basically want to reset your provider to 0, instead of setting the value directly, you can try this:
ref.refresh(countProvider);
Upvotes: 0