Cardを使ってみた。
問題
Cardのchildに指定したものが、Cardの四隅からはみ出る。。
試したこと
コードはこんな感じで非常にシンプル。128x128のCardを2つ作成。
一つ目は何も指定なしのContainerを入れたCard, 二つ目はContainer(color=yellow)を入れたCardです。
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox.fromSize(
size: Size(128, 128),
child: Card(
child: Container(),
),
),
SizedBox.fromSize(
size: Size(128, 128),
child: Card(
child: Container(
color: Colors.yellow.withOpacity(0.5),
),
),
),
],
),
);
}
Simulatorでみると、まあ問題ない。
結局このような感じでCardの中のContainerでdecoracationを指定するとはみ出ないだろう・・・と思った。
final shape = CardTheme.of(context).shape ?? const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0)),
);
...
SizedBox.fromSize(
size: Size(128, 128),
child: Card(
color: Colors.white,
shape: shape,
child: Container(
decoration: ShapeDecoration(
shape: shape,
color: Colors.yellow.withOpacity(0.5),
),
child: Column(
children: [
Container(height: 36, color: Colors.blue),
],
),
),
),
),
これで解決なのかと思ったら Container -> child に指定したものがはみ出る。
なんなのこれ。。
解決
https://stackoverflow.com/questions/55316539/rounded-corner-card-widget-with-right-border-in-flutter を参考にしてClipPathでくくったら解決した。
final shape = CardTheme.of(context).shape ?? const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0)),
);
...
SizedBox.fromSize(
size: Size(128, 128),
child: Card(
color: Colors.white,
shape: shape,
child: ClipPath(
clipper: ShapeBorderClipper(
shape: shape,
),
child: Container(
color: Colors.yellow.withOpacity(0.5),
child: Column(
children: [
Container(height: 36, color: Colors.blue),
],
),
),
),
),
),
試してないけど、Cardじゃなくても同じようなことが言えるんだろうなあ。
(12/6追加)解決その2
Cardに clipBehavior
というパラメータがありそれでも解決できることがわかった。
Clip.antiAliasWithSaveLayer
は非常に遅いというのが書いてあるので、ひとまずhardEdge
と antiAlias
を試してそれぞれの左上の隅を確認してみた。
Macのプレビューアプリを使い拡大してみた結果です。
左からhardEdge
, antiAlias
, ClipPath
を使った例, 何もchildを含めないCardの順です。
これをみると、ドキュメント通りやはりhardEdge
は荒い。拡大しなくてもその荒さがわかるぐらい。
一方、antiAlias
, ClipPath
を使った例、この2つはあまり遜色なかった。
どっちでもいいけど手軽さやメンテナンス性を考えるとantiAlias
を使う方が圧倒的に良いと考える。
ClipPath
を使った実装は、後から見た人はなぜこういう作りにしている?と疑問に思いそうなので。