Closed leavky closed 2 weeks ago
Hi @leavky!
Could you change the example to generate the same problem reported? I believe you are rebuilding the state in your application somewhere you shouldn't be.
In the example, each area has a Widget with state and this is not lost when moving the mouse over the divider.
import 'package:flutter/material.dart';
import 'package:multi_split_view/multi_split_view.dart';
void main() => runApp(const MultiSplitViewExampleApp());
class MultiSplitViewExampleApp extends StatelessWidget {
const MultiSplitViewExampleApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MultiSplitViewExample(),
);
}
}
class MultiSplitViewExample extends StatefulWidget {
const MultiSplitViewExample({Key? key}) : super(key: key);
@override
MultiSplitViewExampleState createState() => MultiSplitViewExampleState();
}
class MultiSplitViewExampleState extends State<MultiSplitViewExample> {
final MultiSplitViewController _controller = MultiSplitViewController();
@override
void initState() {
super.initState();
_controller.areas = [
Area(builder: (c, a) => const MyStatefulWidget()),
Area(builder: (c, a) => const MyStatefulWidget())
];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Multi Split View Example')),
body: MultiSplitViewTheme(
data: MultiSplitViewThemeData(
dividerPainter: DividerPainters.grooved2()),
child: MultiSplitView(controller: _controller))
// body: horizontal,
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => MyState();
}
class MyState extends State<MyStatefulWidget> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(onPressed: _incCount, child: Text('$_count')));
}
void _incCount() {
setState(() {
_count++;
});
}
}
I don't understand what is not possible related to vscode. Do you mean the column of lines of code? You could create an area with a fixed width but in this case, I think a Row would be enough.
Thank you reply, after test i found the problem, when child params is parent params, the child can rebuild.
import 'package:flutter/material.dart';
import 'package:multi_split_view/multi_split_view.dart';
void main() => runApp(const MultiSplitViewExampleApp());
class MultiSplitViewExampleApp extends StatelessWidget {
const MultiSplitViewExampleApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MultiSplitViewExample(
title: "love love",
),
);
}
}
class MultiSplitViewExample extends StatefulWidget {
const MultiSplitViewExample({Key? key, required this.title}) : super(key: key);
final String title;
@override
MultiSplitViewExampleState createState() => MultiSplitViewExampleState();
}
class MultiSplitViewExampleState extends State<MultiSplitViewExample> {
final MultiSplitViewController _controller = MultiSplitViewController();
@override
void initState() {
super.initState();
_controller.areas = [Area(builder: (c, a) => const MyStatefulWidget(title: "one")), Area(builder: (c, a) => MyStatefulWidget(title: widget.title))];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Multi Split View Example')),
body: MultiSplitViewTheme(data: MultiSplitViewThemeData(dividerPainter: DividerPainters.grooved2()), child: MultiSplitView(controller: _controller))
// body: horizontal,
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<StatefulWidget> createState() => MyState();
}
class MyState extends State<MyStatefulWidget> {
int _count = 0;
@override
Widget build(BuildContext context) {
print("MyStatefulWidget build");
return Center(child: ElevatedButton(onPressed: _incCount, child: Text('${widget.title} $_count')));
}
void _incCount() {
setState(() {
_count++;
});
}
}
@caduandrade Is there a solution, please?
Same problem for me. When the mouse is houver the divider, the Area rebuid again, even if not changed the size.
Hey guys! @leavky and @rodolfogoulart, in fact the areas are rebuilt but this is expected ok? Hover changes the state of the component, causing it to rebuild itself. This happens to change the cursor, apply animation, etc. But this is not a problem as you can see in the example, the states of the areas remain the same. Flutter is very efficient at this. This rebuild is irrelevant to performance.
@leavky, you must have a problem with the state of your component. Note that using a setState
in the parent widget should not affect the state of your widget. Maybe you are implementing code out of state.
@leavky,
Try isolating your tree. In this example, the tree would probably also expand again when clicking the parent's "rebuild" button.
import 'package:flutter/material.dart';
void main() => runApp(const ExampleApp());
class ExampleApp extends StatelessWidget {
const ExampleApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Scaffold(body: ParentWidget()));
}
}
class ParentWidget extends StatefulWidget {
const ParentWidget({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => ParentWidgetState();
}
class ParentWidgetState extends State<ParentWidget> {
@override
Widget build(BuildContext context) {
print("Rebuilding parent...");
return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
Center(
child: ElevatedButton(
onPressed: _rebuild, child: const Text('Rebuild'))),
// not using const to rebuild
Expanded(child: MyWrongStatefulWidget())
]);
}
void _rebuild() {
setState(() {});
}
}
class MyWrongStatefulWidget extends StatefulWidget {
const MyWrongStatefulWidget({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => MyWrongState();
}
class MyWrongState extends State<MyWrongStatefulWidget> {
bool _expanded = false;
@override
void didUpdateWidget(covariant MyWrongStatefulWidget oldWidget) {
super.didUpdateWidget(oldWidget);
// its wrong
_expanded = false;
}
@override
Widget build(BuildContext context) {
print('build');
return Center(
child: ElevatedButton(
onPressed: _onClick, child: Text('Expanded: $_expanded')));
}
void _onClick() {
setState(() {
_expanded = !_expanded;
});
}
}
@caduandrade (foi mal meu ingles kkkkkk, vi que tu é BR tbm depois, mas vou colocar em ingles pra ficar para todos)
in fact the areas are rebuilt but this is expected ok?
I think that is not necessary to rebuild the whole area just because a houver on the divider, the divider animations, cursor, etc, can be managed on a separeted state. On my case, i have some areas that use a FutureBuilder, this was causing the area to trigger another build and to call a future function.
@rodolfogoulart, thanks for the contribution! Valeu! Ficou ótimo.
@leavky, maybe @rodolfogoulart 's merge request will solve your problem.
I'll publish the new version by tomorrow, ok?
@rodolfogoulart, thanks for the contribution! Valeu! Ficou ótimo.
@leavky, maybe @rodolfogoulart 's merge request will solve your problem.
I'll publish the new version by tomorrow, ok?
Thanks~
Version 3.2.0 released.
Tks guys!
First of all, thank you very much for creating this package. When my mouse hovers over the Divider, it refreshes all the areas, which causes some areas to have abnormal states. like this:
On the other hand, creating split views similar to those in vscode is not feasible, and I think this could be taken as a reference. https://github.com/nank1ro/flutter-shadcn-ui/blob/main/lib/src/components/resizable.dart