Add Ink.image clip examples (#93799)
This commit is contained in:
parent
25b37bab1e
commit
75e2470302
55
examples/api/lib/material/ink/ink.image_clip.0.dart
Normal file
55
examples/api/lib/material/ink/ink.image_clip.0.dart
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// Flutter code sample for Image.frameBuilder
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(MaterialApp(
|
||||||
|
title: 'Flutter Code Sample',
|
||||||
|
home: Scaffold(
|
||||||
|
appBar: AppBar(title: const Text('Flutter Code Sample')),
|
||||||
|
body: const Center(
|
||||||
|
child: MyStatelessWidget(
|
||||||
|
image: NetworkImage('https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyStatelessWidget extends StatelessWidget {
|
||||||
|
const MyStatelessWidget({Key? key, required this.image}) : super(key: key);
|
||||||
|
|
||||||
|
final ImageProvider image;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
child: Ink.image(
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
width: 300,
|
||||||
|
height: 300,
|
||||||
|
image: image,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {/* ... */},
|
||||||
|
child: const Align(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(10.0),
|
||||||
|
child: Text(
|
||||||
|
'PUFFIN',
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
57
examples/api/lib/material/ink/ink.image_clip.1.dart
Normal file
57
examples/api/lib/material/ink/ink.image_clip.1.dart
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// Flutter code sample for Image.frameBuilder
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(MaterialApp(
|
||||||
|
title: 'Flutter Code Sample',
|
||||||
|
home: Scaffold(
|
||||||
|
appBar: AppBar(title: const Text('Flutter Code Sample')),
|
||||||
|
body: const Center(
|
||||||
|
child: MyStatelessWidget(
|
||||||
|
image: NetworkImage('https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyStatelessWidget extends StatelessWidget {
|
||||||
|
const MyStatelessWidget({Key? key, required this.image}) : super(key: key);
|
||||||
|
|
||||||
|
final ImageProvider image;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
child: Material(
|
||||||
|
child: Ink.image(
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
width: 300,
|
||||||
|
height: 300,
|
||||||
|
image: image,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {/* ... */},
|
||||||
|
child: const Align(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(10.0),
|
||||||
|
child: Text(
|
||||||
|
'PUFFIN',
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
34
examples/api/test/material/ink/ink.image_clip.0.test.dart
Normal file
34
examples/api/test/material/ink/ink.image_clip.0.test.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_api_samples/material/ink/ink.image_clip.0.dart' as example;
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
const List<int> kTransparentImage = <int>[
|
||||||
|
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49,
|
||||||
|
0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06,
|
||||||
|
0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4, 0x89, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44,
|
||||||
|
0x41, 0x54, 0x78, 0x9C, 0x63, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x0D,
|
||||||
|
0x0A, 0x2D, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
|
||||||
|
];
|
||||||
|
|
||||||
|
testWidgets('Ink ancestor material is not clipped', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: example.MyStatelessWidget(
|
||||||
|
image: MemoryImage(Uint8List.fromList(kTransparentImage)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final Finder inkMaterialFinder = find.ancestor(of: find.byType(Ink), matching: find.byType(Material));
|
||||||
|
expect(find.ancestor(of: inkMaterialFinder, matching: find.byType(ClipRRect)), findsNothing);
|
||||||
|
});
|
||||||
|
}
|
34
examples/api/test/material/ink/ink.image_clip.1.test.dart
Normal file
34
examples/api/test/material/ink/ink.image_clip.1.test.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_api_samples/material/ink/ink.image_clip.1.dart' as example;
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
const List<int> kTransparentImage = <int>[
|
||||||
|
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49,
|
||||||
|
0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06,
|
||||||
|
0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4, 0x89, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44,
|
||||||
|
0x41, 0x54, 0x78, 0x9C, 0x63, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x0D,
|
||||||
|
0x0A, 0x2D, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
|
||||||
|
];
|
||||||
|
|
||||||
|
testWidgets('Ink ancestor material is clipped', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: example.MyStatelessWidget(
|
||||||
|
image: MemoryImage(Uint8List.fromList(kTransparentImage)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final Finder inkMaterialFinder = find.ancestor(of: find.byType(Ink), matching: find.byType(Material));
|
||||||
|
expect(find.ancestor(of: inkMaterialFinder, matching: find.byType(ClipRRect)), findsOneWidget);
|
||||||
|
});
|
||||||
|
}
|
@ -104,6 +104,27 @@ import 'material.dart';
|
|||||||
/// ```
|
/// ```
|
||||||
/// {@end-tool}
|
/// {@end-tool}
|
||||||
///
|
///
|
||||||
|
/// What to do if you want to clip this [Ink.image]?
|
||||||
|
///
|
||||||
|
/// {@tool dartpad}
|
||||||
|
/// Wrapping the [Ink] in a clipping widget directly will not work since the
|
||||||
|
/// [Material] it will be printed on is responsible for clipping.
|
||||||
|
///
|
||||||
|
/// In this example the image is not being clipped as expected. This is because
|
||||||
|
/// it is being rendered onto the Scaffold body Material, which isn't wrapped in
|
||||||
|
/// the [ClipRRect].
|
||||||
|
///
|
||||||
|
/// ** See code in examples/api/lib/material/ink/ink.image_clip.0.dart **
|
||||||
|
/// {@end-tool}
|
||||||
|
///
|
||||||
|
/// {@tool dartpad}
|
||||||
|
/// One solution would be to deliberately wrap the [Ink.image] in a [Material].
|
||||||
|
/// This makes sure the Material that the image is painted on is also responsible
|
||||||
|
/// for clipping said content.
|
||||||
|
///
|
||||||
|
/// ** See code in examples/api/lib/material/ink/ink.image_clip.1.dart **
|
||||||
|
/// {@end-tool}
|
||||||
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
/// * [Container], a more generic form of this widget which paints itself,
|
/// * [Container], a more generic form of this widget which paints itself,
|
||||||
|
@ -1159,6 +1159,18 @@ class _InkResponseState extends State<_InkResponseStateWidget>
|
|||||||
/// ancestor to the ink well). The [MaterialType.transparency] material
|
/// ancestor to the ink well). The [MaterialType.transparency] material
|
||||||
/// kind can be used for this purpose.
|
/// kind can be used for this purpose.
|
||||||
///
|
///
|
||||||
|
/// ### InkWell isn't clipping properly
|
||||||
|
///
|
||||||
|
/// If you want to clip an InkWell or any [Ink] widgets you need to keep in mind
|
||||||
|
/// that the [Material] that the Ink will be printed on is responsible for clipping.
|
||||||
|
/// This means you can't wrap the [Ink] widget in a clipping widget directly,
|
||||||
|
/// since this will leave the [Material] not clipped (and by extension the printed
|
||||||
|
/// [Ink] widgets as well).
|
||||||
|
///
|
||||||
|
/// An easy solution is to deliberately wrap the [Ink] widgets you want to clip
|
||||||
|
/// in a [Material], and wrap that in a clipping widget instead. See [Ink] for
|
||||||
|
/// an example.
|
||||||
|
///
|
||||||
/// ### The ink splashes don't track the size of an animated container
|
/// ### The ink splashes don't track the size of an animated container
|
||||||
/// If the size of an InkWell's [Material] ancestor changes while the InkWell's
|
/// If the size of an InkWell's [Material] ancestor changes while the InkWell's
|
||||||
/// splashes are expanding, you may notice that the splashes aren't clipped
|
/// splashes are expanding, you may notice that the splashes aren't clipped
|
||||||
|
@ -91,6 +91,7 @@ abstract class MaterialInkController {
|
|||||||
/// 1. Clipping: If [clipBehavior] is not [Clip.none], Material clips its widget
|
/// 1. Clipping: If [clipBehavior] is not [Clip.none], Material clips its widget
|
||||||
/// sub-tree to the shape specified by [shape], [type], and [borderRadius].
|
/// sub-tree to the shape specified by [shape], [type], and [borderRadius].
|
||||||
/// By default, [clipBehavior] is [Clip.none] for performance considerations.
|
/// By default, [clipBehavior] is [Clip.none] for performance considerations.
|
||||||
|
/// See [Ink] for an example of how this affects clipping [Ink] widgets.
|
||||||
/// 2. Elevation: Material elevates its widget sub-tree on the Z axis by
|
/// 2. Elevation: Material elevates its widget sub-tree on the Z axis by
|
||||||
/// [elevation] pixels, and draws the appropriate shadow.
|
/// [elevation] pixels, and draws the appropriate shadow.
|
||||||
/// 3. Ink effects: Material shows ink effects implemented by [InkFeature]s
|
/// 3. Ink effects: Material shows ink effects implemented by [InkFeature]s
|
||||||
|
Loading…
x
Reference in New Issue
Block a user