-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Closed
Labels
c: regressionIt was better in the past than it is nowIt was better in the past than it is nowframeworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.
Description
This is similar to an old issue from the old issue tracker. This new issue surfaced because of that old issue's fix (c44dd17). When child.parentData = null; is removed again, then we no longer see this new issue's behavior (though we do see the old one's).
Anyway, the example is 2 stacks that can be tapped to move up or down on the screen. Notably, the lower part of the screen will also wrap the Stack in a Listener, which causes problems when a Disk widget is moved from the bottom stack back to the top stack.
This is lib/main.dart.
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class Disk extends StatefulComponent {
String name;
Function cb;
Disk(String name, bool useKey, this.cb) :
super(key: useKey ? new GlobalObjectKey(name) : null),
name = name;
DiskState createState() => new DiskState();
}
class DiskState extends State<Disk> {
Point _oldLocation;
@override
void initState() {
print("init ${config.name}");
super.initState();
_checkPosition();
}
void _checkPosition() {
scheduler.requestPostFrameCallback((Duration d) {
print("Post Frame Callback of ${config.name} ${d}");
Point newLocation = getGlobalPosition();
print("Moved from ${_oldLocation} to ${newLocation}");
setState(() {
_oldLocation = newLocation;
});
});
}
@override
void didUpdateConfig(Disk oldConfig) {
print("Update ${oldConfig.name} to ${config.name}");
_checkPosition();
}
Point getGlobalPosition() {
RenderBox box = context.findRenderObject();
return box.localToGlobal(Point.origin);
}
Widget build(BuildContext context) {
return new InkWell(
onTap: config.cb,
child: new Container(
decoration: new BoxDecoration(backgroundColor: Colors.blue[500]),
width: 30.0,
height: 30.0,
child: new Text(config.name)
)
);
}
}
class Holder extends StatefulComponent {
HolderState createState() => new HolderState();
}
class HolderState extends State<Holder> {
Map<String, bool> data = new Map<String, bool>();
void initState() {
super.initState();
data["a"] = true;
data["b"] = true;
}
Function _makeChangeDataCb(String name) {
return () {
setState(() {
data[name] = !data[name];
});
};
}
Widget build(BuildContext context) {
// Note1: Set to false to see the effect go away. Set to true, to see the shifted effect in printouts.
bool useKey = true;
List<Widget> trueKids = new List<Widget>();
List<Widget> falseKids = new List<Widget>();
data.forEach((String name, bool isTop) {
Disk disk = new Disk(name, useKey, _makeChangeDataCb(name));
Widget k = disk;
// Note2: If you add "|| true", then the effect disappears. The widget tree must misalign for the effect to occur.
if (!isTop) {
// Note3: This listener gets in the way of the position computation and makes the transform occur twice during localToGlobal. But only when there is a key.
k = new Listener(
child: disk
);
}
Widget kid = new Positioned(
top: 5.0,
left: 5.0,
child: k
);
if (isTop) {
trueKids.add(kid);
} else {
falseKids.add(kid);
}
});
return new Column([
new Container(
decoration: new BoxDecoration(backgroundColor: Colors.red[500]),
child: new Stack(trueKids),
width: 60.0,
height: 60.0
),
new Container(
decoration: new BoxDecoration(backgroundColor: Colors.red[500]),
child: new Stack(falseKids),
width: 60.0,
height: 60.0
),
new FlatButton(child: new Text("Debug"), onPressed: debugDumpApp)
]);
}
}
void main() {
runApp(new Holder());
}
You can use this pubspec.yaml and pub run sky_tools start
name: keyedWidgetsPosition
dependencies:
flutter: "0.0.18"
sky_tools: any
Or you can run the example with the new way of launching flutter apps.
Metadata
Metadata
Assignees
Labels
c: regressionIt was better in the past than it is nowIt was better in the past than it is nowframeworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.