magnifierConfiguration property

TextMagnifierConfiguration? magnifierConfiguration
final

The configuration for the magnifier of this text field.

By default, builds a CupertinoTextMagnifier on iOS and TextMagnifier on Android, and builds nothing on all other platforms. To suppress the magnifier, consider passing TextMagnifierConfiguration.disabled.

This magnifying glass is useful for scenarios on mobile devices where the user's finger may be covering part of the screen where a granular action is being performed, such as navigating a small cursor with a drag gesture, on an image or text.

This sample demonstrates how to customize the magnifier that this text field uses.

To see it in action, copy and run this code snippet on DartPad.

import 'package:flutter/foundation.dart';
import 'package:material_ui/material_ui.dart';

void main() => runApp(const TextMagnifierExampleApp(text: 'Hello world!'));

class TextMagnifierExampleApp extends StatelessWidget {
  const TextMagnifierExampleApp({
    super.key,
    this.textDirection = TextDirection.ltr,
    required this.text,
  });

  final TextDirection textDirection;
  final String text;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Padding(
          padding: const .symmetric(horizontal: 48.0),
          child: Center(
            child: TextField(
              textDirection: textDirection,
              // Create a custom magnifier configuration that
              // this `TextField` will use to build a magnifier with.
              magnifierConfiguration: TextMagnifierConfiguration(
                magnifierBuilder:
                    (_, _, ValueNotifier<MagnifierInfo> magnifierInfo) =>
                        CustomMagnifier(magnifierInfo: magnifierInfo),
              ),
              controller: TextEditingController(text: text),
            ),
          ),
        ),
      ),
    );
  }
}

class CustomMagnifier extends StatelessWidget {
  const CustomMagnifier({super.key, required this.magnifierInfo});

  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: (BuildContext context, MagnifierInfo currentMagnifierInfo, _) {
        // We want to position the magnifier at the global position of the gesture.
        Offset 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,
          ),
        );
      },
    );
  }
}

Implementation

// TODO(framework): Replace the following block with a @dartpad directive
// when it's supported. https://github.com/dart-lang/dartdoc/issues/4123
/// {@macro material_ui.dartpad_guide}
///
/// {@example /example/lib/text_field/text_field_magnifier.0.dart#body}
///
/// </callout-box>
final TextMagnifierConfiguration? magnifierConfiguration;