Issue
I have a simple layout with an Image widget encapsulated in a FittedBox. I want to take it's size and position so I put a key on Image widget and get it from the initState:
final GlobalKey imgKey = GlobalKey();
@override
void initState() {
SchedulerBinding.instance?.addPostFrameCallback((timeStamp) async {
await ModalRoute.of(context)?.didPush(); //wait opening transition
final keyPosContext = imgKey.currentContext;
if (keyPosContext != null){
final renderPlan = keyPosContext.findRenderObject() as RenderBox;
final pos = renderPlan.localToGlobal(Offset.zero);
if(pos != planOffset || renderPlan.size != planSize) {
setState(() {
planOffset = pos;
planSize = renderPlan.size;
});
}
}
});
super.initState();
}
the layout:
Widget build(BuildContext context){
return Stack(
children: [
Positioned(
top: 0, left: 100, right: 100, height: 30,
child: Align(alignment: Alignment.center,
child: Text('$title'),
),
),
Positioned(
top: 30, left: 0, right: 0, bottom: 0,
child: DragTarget<DraggableData>(
onMove: onMove,
onAccept: onAccept,
builder: (BuildContext context, List candidateData, List rejectedData) {
File img = File(myPlan);
if (img.existsSync()) {
return FittedBox(
fit: BoxFit.contain,
child: Image.file(img, key: imgKey),
);
} else
return Container();
}
),
),
Positioned(//TEST
top: planOffset.dy,
left: planOffset.dx,
height: planSize.height,
width: planSize.width,
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.green, width: 2),
),
),
),
]
);
}
The last Positioned is just a green rect to test the values. I take the right position but the size is wrong: I take the original image size (400*300 in my case) regardless of the fitted size...
Solution
You could can use this widget to get the size at run time.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
typedef void OnWidgetSizeChange(Size size);
class MeasureSize extends SingleChildRenderObjectWidget {
final OnWidgetSizeChange onChange;
const MeasureSize({Key? key, required this.onChange, required Widget child}) : super(key: key, child: child);
@override
RenderObject createRenderObject(BuildContext context) => _MeasureSizeRenderObject(onChange);
}
class _MeasureSizeRenderObject extends RenderProxyBox {
Size? oldSize;
final OnWidgetSizeChange onChange;
_MeasureSizeRenderObject(this.onChange);
@override
void performLayout() {
super.performLayout();
Size newSize = child!.size;
// if (oldSize == newSize) return;
oldSize = newSize;
WidgetsBinding.instance!.addPostFrameCallback((_) => onChange(newSize));
}
}
To get the size
...
Positioned(
top: 30, left: 0, right: 0, bottom: 0,
child: DragTarget<DraggableData>(
onMove: onMove,
onAccept: onAccept,
builder: (BuildContext context, List candidateData, List rejectedData) {
File img = File(myPlan);
if (img.existsSync()) {
return FittedBox(
fit: BoxFit.contain,
child: MeasureSize(
child: Image.file(img, key: imgKey),
onChange: (Size newSize) {
setState(() {
planSize = newSize;
});
},
),
);
} else
return Container();
}
),
),
...
Answered By - Dennis Mwea
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.