環境
- Android Studio: Flamingo 2022.2.1
- Flutter: 3.7.12
考え方
- Containerの右下に切り抜きを作る → Clipperをつかう
- めくれた感じをつくる = 右下に小さいContainerを重ねる → Stackをつかう
完成イメージ
コード
サンプルコード
import 'package:flutter/material.dart';
/// 折れたところのサイズを設定する
const _clipSize = Size(40, 40);
class OretaContainerPage extends StatefulWidget {
const OretaContainerPage({super.key});
@override
State<StatefulWidget> createState() => _OretaContainerState();
}
class _OretaContainerState extends State<StatefulWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('紙の端が折れたようなContainer')),
body: _createContainer(),
);
}
Widget _createContainer() {
// Positionedで右下にめくれたようなUIを配置する
return Padding(
padding: const EdgeInsets.all(8),
child: ClipPath(
clipBehavior: Clip.antiAlias,
clipper: PaperClipper(),
child: Stack(
children: [
Container(
width: double.infinity,
height: 200,
color: Colors.blue.shade100,
),
Positioned(
bottom: 0,
right: 0,
child: Container(
width: _clipSize.width,
height: _clipSize.height,
color: Colors.blue.shade300,
),
),
],
),
),
);
}
}
/// 角折れを表現するためのClipper
class PaperClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
// 折れてるところだけを切り抜く
final path = Path();
path.lineTo(0, 0); // Start
path.lineTo(size.width, 0); // 右上
path.lineTo(size.width, size.height - _clipSize.height); // 折れてるところ
path.lineTo(size.width - _clipSize.width, size.height); // 折れてるところ
path.lineTo(0, size.height); // End
path.close();
return path;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}
ここのコードには載せてませんが、
Materialで影とかつけたりしたらいい感じのUIになると思います。
【6/9 追記】
ClipしたUIに影をつけるのは、Materialでくくるだけではダメな模様。
→ stackoverflowに質問あった。
https://stackoverflow.com/questions/54753355/how-to-make-suitable-border-and-shadow-for-a-widget-created-by-customclipper
補足
- CustomClipperの、getPath()の繋げ方のイメージ
参考サイト
- Clipperの使い方
この紙の端が折れたUI、って正式名称はなんて名前なんでしょうか?
めくれてる、とか?
ググってもでてこなくて、自力でつくりました…
そもそも自力でつくるものではないのでしょうか? そういうプラグインがある??
UIに詳しい方、教えてください。
【2023/7/3 追記】
この紙の端が折れたUI、って正式名称はなんて名前なんでしょうか?
「ドッグイア」というらしいです。