Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [WidgetStateOutlinedBorder].

void main() => runApp(const WidgetStateOutlinedBorderExampleApp());

class WidgetStateOutlinedBorderExampleApp extends StatelessWidget {
const WidgetStateOutlinedBorderExampleApp({super.key});

@override
Widget build(BuildContext context) {
return const MaterialApp(home: WidgetStateOutlinedBorderExample());
}
}

class SelectedBorder extends RoundedRectangleBorder
implements WidgetStateOutlinedBorder {
const SelectedBorder();

@override
OutlinedBorder? resolve(Set<WidgetState> states) {
if (states.contains(WidgetState.selected)) {
return const RoundedRectangleBorder();
}
return null; // Defer to default value on the theme or widget.
}
}

class WidgetStateOutlinedBorderExample extends StatefulWidget {
const WidgetStateOutlinedBorderExample({super.key});

@override
State<WidgetStateOutlinedBorderExample> createState() =>
_WidgetStateOutlinedBorderExampleState();
}

class _WidgetStateOutlinedBorderExampleState
extends State<WidgetStateOutlinedBorderExample> {
bool isSelected = true;

@override
Widget build(BuildContext context) {
return Material(
child: FilterChip(
label: const Text('Select chip'),
selected: isSelected,
onSelected: (bool value) {
setState(() {
isSelected = value;
});
},
shape: const SelectedBorder(),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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,
),
);
},
);
}
}
Loading
Loading