Closed Sten435 closed 3 months ago
return MultiSplitView(
controller: controller1,
onDividerDoubleTap: (dividerIndex) {
controller1.getArea(dividerIndex).setFlex(2);
controller1.getArea(dividerIndex).setSize(150);
},
dividerBuilder: (axis, index, resizable, dragging, highlighted, themeData) {
return const VerticalDivider(indent: 0, endIndent: 0, width: 0, thickness: 0);
},
);
You should make the AreaHelper public
@internal
class AreaHelper {
static Key keyFrom({required Area area}) {
return area._key;
}
/// Sets the area flex value.
static void setFlex({required Area area, required double flex}) {
flex = NumUtil.fix('flex', flex);
if (area.min != null) {
flex = math.max(flex, area.min!);
}
area._flex = flex;
}
/// Sets the area size value.
static void setSize({required Area area, required double? size}) {
if (size != null) {
size = NumUtil.fix('size', size);
}
area._size = size;
}
/// Sets the area min value.
static void setMin({required Area area, required double? min}) {
if (min != null) {
min = math.max(0, min);
}
area._min = min;
}
/// Sets the area max value.
static void setMax({required Area area, required double? max}) {
area._max = max;
}
/// Sets the area index.
static void setIndex({required Area area, required int index}) {
area._index = index;
}
}
I dont want to trigger the initState of my widgets when i want to programaticly change them.
Hi @Sten435!
You cannot directly change the flex in the Area
class as this would make the layout inconsistent. But you can change it through the controller, you can define the areas in it:
controller.areas = [...]
Sorry, I didn't understand your problem with the initState
of your Widgets. I believe that in this case, you did something wrong, forcing the creation of a new state. Flutter is very efficient at recreating widgets and reusing states.
An example of inconsistency: the user could set all areas to flex 0.
The algorithm that adjusts inconsistency is executed only when setting the areas for performance reasons.
I think that in your proposal, there shouldn't even be Helpers. It should allow changing values directly in the Area
class. But it would be important to perform the inconsistency adjustment efficiently. (know how to execute only when there is a change?). And of course think about all the cases where perhaps you should throw an exception.
I'm going to think if there could be a flag to mark that the area has been changed. So in the build, the incostence algorithm would not always execute.
Hi @Sten435!
You cannot directly change the flex in the
Area
class as this would make the layout inconsistent. But you can change it through the controller, you can define the areas in it:controller.areas = [...]
Sorry, I didn't understand your problem with the
initState
of your Widgets. I believe that in this case, you did something wrong, forcing the creation of a new state. Flutter is very efficient at recreating widgets and reusing states.An example of inconsistency: the user could set all areas to flex 0.
The algorithm that adjusts inconsistency is executed only when setting the areas for performance reasons.
I think that in your proposal, there shouldn't even be Helpers. It should allow changing values directly in the
Area
class. But it would be important to perform the inconsistency adjustment efficiently. (know how to execute only when there is a change?). And of course think about all the cases where perhaps you should throw an exception.I'm going to think if there could be a flag to mark that the area has been changed. So in the build, the incostence algorithm would not always execute.
Hey @caduandrade 👋
For example
When you have 2 areas.
void update() {
controller.area = [
Area(
flex: 2,
builder: ()=> StatefulWidget(),
),
Area(
flex: 1,
builder: ()=> StatefulWidgetSecond(),
),
];
}
When i call update() the initState method from the statefullwidgets are both called 😯.
This is not expected behavior.
This can be fixed by my example e.g. my pull request.
Or give the users the ability to add a 'Key' e.g. ValueKey(...) to the area. This would also fix the issue.
The reason the initState is triggered, is because you create a UniqueKey() in the area. And that will always trigger the initState function. 🙃
Hi @Sten435!
Now I understand your initState
problem. The UniqueKey
is necessary for the area because if the number of areas changes, Flutter also resets the state because its tree structure changes. But in your case, as you instantiated a new area, you also created a new UniqueKey
To make your life even more difficult, the Area's builder does not have the key to reuse it.
I will check the following points:
1) If there is any problem with allowing reuse.
2) If it is possible to clone the Area
by changing some values.
3) Change the values directly in the Area
.
Even if you don't use them all, they are valid.
Hi @Sten435!
Now I understand your
initState
problem. TheUniqueKey
is necessary for the area because if the number of areas changes, Flutter also resets the state because its tree structure changes. But in your case, as you instantiated a new area, you also created a newUniqueKey
To make your life even more difficult, the Area's builder does not have the key to reuse it.
I will check the following points:
1) If there is any problem with allowing reuse.
2) If it is possible to clone the
Area
by changing some values.3) Change the values directly in the
Area
.Even if you don't use them all, they are valid.
Hey @caduandrade 👋
I don't quite understand your last words: Even if you don't use them all, they are valid.?
What do you mean with this?
Could you also explain why tou cannot simply reuse the same key?
And why a user can't just give a key to the area?
Hi @Sten435 !
Just with this change committed you can change the areas by reusing the same id. I replaced the internal key with the id.
I will think about the cost/benefit of changing values directly in the Area. To do this, it is also necessary to decide whether a single change would notify the widget or whether it should be done within a setState
.
Hi @Sten435 !
Just with this change committed you can change the areas by reusing the same id. I replaced the internal key with the id.
I will think about the cost/benefit of changing values directly in the Area. To do this, it is also necessary to decide whether a single change would notify the widget or whether it should be done within a
setState
.
Hey 👋 @caduandrade
Thanks for the fast response.
Could you also update pub dev? I saw that the latest update was over 30d ago.
Big thanks for the change.
Version 3.2.0 released.
Now you can reuse the id to build the new areas ok?
Add an option to change the size of flex using a controller, for example double tap on a divider should reset the position to the first position.
This is kinda basic, kinda weird something this simple is not already implemented ?