Unverified Commit 75e24703 authored by Markus Aksli's avatar Markus Aksli Committed by GitHub

Add Ink.image clip examples (#93799)

parent 25b37bab
// 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,
),
),
),
),
),
),
);
}
}
// 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,
),
),
),
),
),
),
),
);
}
}
// 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);
});
}
// 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'; ...@@ -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> ...@@ -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 { ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment