parent
614bf1a526
commit
d5b4aa6c94
5 changed files with 131 additions and 42 deletions
@ -0,0 +1,68 @@ |
||||
import 'package:flutter/foundation.dart'; |
||||
import 'package:flutter/material.dart'; |
||||
|
||||
class CustomMagnifier extends StatelessWidget { |
||||
const CustomMagnifier({required this.magnifierInfo, super.key}); |
||||
|
||||
static const Size magnifierSize = Size(200, 200); |
||||
|
||||
// This magnifier will consume some text data and position itself |
||||
// based on the info in the magnifier. |
||||
final ValueNotifier<MagnifierInfo> magnifierInfo; |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
// Use a value listenable builder because we want to rebuild |
||||
// every time the text selection info changes. |
||||
// `CustomMagnifier` could also be a `StatefulWidget` and call `setState` |
||||
// when `magnifierInfo` updates. This would be useful for more complex |
||||
// positioning cases. |
||||
return ValueListenableBuilder<MagnifierInfo>( |
||||
valueListenable: magnifierInfo, |
||||
builder: (context, currentMagnifierInfo, _) { |
||||
// We want to position the magnifier at the global position of the gesture. |
||||
var magnifierPosition = currentMagnifierInfo.globalGesturePosition; |
||||
|
||||
// You may use the `MagnifierInfo` however you'd like: |
||||
// In this case, we make sure the magnifier never goes out of the current line bounds. |
||||
magnifierPosition = Offset( |
||||
clampDouble( |
||||
magnifierPosition.dx, |
||||
currentMagnifierInfo.currentLineBoundaries.left, |
||||
currentMagnifierInfo.currentLineBoundaries.right, |
||||
), |
||||
clampDouble( |
||||
magnifierPosition.dy, |
||||
currentMagnifierInfo.currentLineBoundaries.top, |
||||
currentMagnifierInfo.currentLineBoundaries.bottom, |
||||
), |
||||
); |
||||
|
||||
// Finally, align the magnifier to the bottom center. The initial anchor is |
||||
// the top left, so subtract bottom center alignment. |
||||
magnifierPosition -= Alignment.bottomCenter.alongSize(magnifierSize); |
||||
|
||||
return Positioned( |
||||
left: magnifierPosition.dx, |
||||
top: magnifierPosition.dy, |
||||
child: RawMagnifier( |
||||
magnificationScale: 2, |
||||
// The focal point starts at the center of the magnifier. |
||||
// We probably want to point below the magnifier, so |
||||
// offset the focal point by half the magnifier height. |
||||
focalPointOffset: Offset(0, magnifierSize.height / 2), |
||||
// Decorate it however we'd like! |
||||
decoration: const MagnifierDecoration( |
||||
shape: StarBorder( |
||||
side: BorderSide( |
||||
color: Colors.green, |
||||
width: 2, |
||||
), |
||||
), |
||||
), |
||||
size: magnifierSize, |
||||
), |
||||
); |
||||
}); |
||||
} |
||||
} |
Loading…
Reference in new issue