Flutter hive clearing box during swiping between tabs - flutter

In my case we have 3 tabs in TabController and in all of this pages we have some data which we want to use them, now on each tab when we are swiping between them we don't have previous data and length of box values is 0, you suppose we have three tab as:
screen_a
screen_b
screen_c
into screen_a we have:
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() =>MyHome();
}
class MyHome extends State<Home> {
late Box<Level> _level;
late List<Level> levels ;
late VideoPlayerController _controller;
#override
void initState() {
super.initState();
_level = Hive.box<Level>('level');
levels = _level.values.toList();
}
#override
Widget build(BuildContext context) {
now on starting application we have many data on screen_a and after swiping on screen_b and going back to screen_a we don't have any data in hive :| :|
what's the problem?

You should store your tabs' data in a bloc or controller class that does not lose state and data when switching between tabs.

It depends on your overall use case and how you want your TabViews to behave, but you can work with the AutomaticKeepAliveClientMixin to ensure that your state of the StatefulWidget stays intact when switching tabs. This also ensures that the content of your StatefulWidget does not have to be rebuild when switching tabs, but will still use resources (just to keep in mind for performance considerations when working with more complex scenarios):
class MyHome extends State<Home> with AutomaticKeepAliveClientMixin {
/// Here you can either add custom logic to determine when
/// this tab should be kept "alive" - for now returning [true]
/// will work out.
#override
bool get wantKeepAlive => true;
...

Related

How do I show a Dialog Box on my home screen as soon as it loads in Flutter?

I want to show a dialog box as soon as my home screen loads up with the dialog box containing 4 clickable images in a grid view. The images will be routed to individual screens. I am unaware of a way to implement this. Could use some help. Thanks.
You need to use stateful widget to show a dialog when screen loads so do it like this,
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
void initState() {
super.initState();
SchedulerBinding.instance?.addPostFrameCallback((_) {
showDialog(); // your dialong goes here
}
}
}
Note when you are using inistate you don't have access to context so you required use a postFrameCallBack so that whenever context is available the function will get executed.

Change loaded Widget outside of Main file (setState not available)

I have a MainScreen() file where I defined two Widgets, side by side:
Left menu (ListTiles).
Main View (rest of screen, to the right).
My issue is that I need to tap the ListTiles on the left and dynamically change the Widget loaded on the Main View.
Any suggestions?
The main view must be stateful for this to work, as you need to trigger a rerender once you tap one of the tiles. You want to pass a callback function from your main screen to your menu of list tiles.
Your best bet is to setup an enum and have each listtile provide the callback with its own enum value.
Once you have the callback in your list of tiles, you can easily pass it onward to the individual tiles. Then, execute the callback function onTap and provide it with the correct enum value.
On your main screen, you just show the correct widget by looking at the current enum value.
class MainScreen extends StatefulWidget {
const MainScreen({Key? key}) : super(key: key);
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
MyEnum _currentTile = MyEnum.Home;
void _callbackFunction(MyEnum tileOption) {
setState(() {
_currentTile = tileOption;
});
}
#override
Widget build(BuildContext context) {
return MyCustomListTile((MyEnum tile) => _callbackFunction(tile) );
}
}

How to use the same BLoC for different widgets in Flutter?

I have 2 custom widgets, and I want to use the same Bloc file.
My Bloc file gets data from the internet in the constructor.
class MyBloc {
// StreamControllers, StreamSinks, Streams ...
MyBloc() {
getDataFromInternet();
}
}
class MyWidget1 extends StatefulWidget {
MyWidget1({Key key}) : super(key: key);
#override
_MyWidget1State createState() => _MyWidget1State();
}
class _MyWidget1State extends State<MyWidget1> {
MyBloc _bloc;
#override
void initState() {
_bloc = MyBloc();
super.initState();
}
}
class MyWidget2 extends StatefulWidget {
MyWidget2({Key key}) : super(key: key);
#override
_MyWidget2State createState() => _MyWidget2State();
}
class _MyWidget2State extends State<MyWidget2> {
MyBloc _bloc;
#override
void initState() {
_bloc = MyBloc();
super.initState();
}
}
My problem is, that it downloads the data every time the screen changes (any of the two widgets appear on the screen).
Should I pass the initialized bloc object to the widgets in the constructors, and not create a new Bloc in the widgets constructor? I don't want to save the data and write logic to check if I already downloaded it or not.
Use this bloc implementation https://bloclibrary.dev/
Your bloc will have single instance with it's single state at the moment. Invoke new state depending on previous and you will never has problems with unneeded queries or something like this.

How to keep checkbox state while browsing between navigation bar items

In Flutter, I have a bottom navigator bar and there are 4 different bottom navigator bar items in it. In the 4th menu item, I have a checkbox widget. While browsing in the navigation bar items I would like the checked or unchecked items situation remains. For example if I uncheck this widget I would like it to stay still "unchecked" while browsing in other navigation bar items. How can I do this? I tried to use key parameter of checkbox but I failed.
You should use AutomaticKeepAliveClientMixin
to keep state Alive while you browse between your items.Extend your state class with it and create an override method wannaKeepAlive and set it to true.Here is an example of a widget using AutomaticKeepAliveClientMixin.
class Example extends StatefulWidget {
#override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> with AutomaticKeepAliveClientMixin {
#override
Widget build(BuildContext context) {
return Container(
);
}
#override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}
Welcome to State management!
Official guideline for state management from Flutter team.
I would recommend to read everything starting from introduction to state management.

How do I preserve the data in my textfield when navigating to another tabview

How do I preserve my data when I navigate between two different tabs in Flutter... Basically what I want to achieve is, on one side of the tab, I see users data, and on the other side of the tab, I want to be able to copy some of those user data and paste into some textfields on the other tab without losing the data in the text fields when I navigate back and forth and still also preserving the level of scrolling I might have done on the tab where the users data show.
You need to use AutomaticKeepAliveClientMixin This will ensure the State instance is not destroyed when leaving the screen.Extend your every tabview's state class with it and create an override method wannaKeepAlive and set it to true.Here is an example of a widget using AutomaticKeepAliveClientMixin.
class Example extends StatefulWidget {
#override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> with AutomaticKeepAliveClientMixin {
#override
Widget build(BuildContext context) {
return Container(
);
}
#override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}