nc-photos/lib/widget/measure.dart
2021-07-25 00:23:08 +08:00

76 lines
1.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
typedef void OnWidgetSizeChanged(Size size);
/// See: https://stackoverflow.com/a/60868972
class MeasureSize extends SingleChildRenderObjectWidget {
final OnWidgetSizeChanged onChange;
const MeasureSize({
Key? key,
required this.onChange,
required Widget child,
}) : super(key: key, child: child);
@override
RenderObject createRenderObject(BuildContext context) {
return _MeasureSizeRenderObject(onChange);
}
}
class _MeasureSizeRenderObject extends RenderProxyBox {
Size? oldSize;
final OnWidgetSizeChanged onChange;
_MeasureSizeRenderObject(this.onChange);
@override
void performLayout() {
super.performLayout();
var newSize = child?.size;
if (newSize == null || oldSize == newSize) return;
oldSize = newSize;
WidgetsBinding.instance!.addPostFrameCallback((_) {
onChange(newSize);
});
}
}
class SliverMeasureExtent extends SingleChildRenderObjectWidget {
const SliverMeasureExtent({
Key? key,
required this.onChange,
required Widget child,
}) : super(key: key, child: child);
@override
RenderObject createRenderObject(BuildContext context) {
return _SliverMeasureExtentRenderObject(onChange);
}
final void Function(double) onChange;
}
class _SliverMeasureExtentRenderObject extends RenderProxySliver {
_SliverMeasureExtentRenderObject(this.onChange);
@override
void performLayout() {
super.performLayout();
var newExent = child?.geometry?.scrollExtent;
if (newExent == null || _oldExtent == newExent) {
return;
}
_oldExtent = newExent;
WidgetsBinding.instance!.addPostFrameCallback((_) => onChange(newExent));
}
final void Function(double) onChange;
double? _oldExtent;
}