LoginSignup
6
3

More than 3 years have passed since last update.

Cardで四隅からはみ出さないようにする

Last updated at Posted at 2019-12-04

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の4隅がはみ出ている。。
image.png

結局このような感じで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 に指定したものがはみ出る。

image.png

なんなのこれ。。

解決

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),
          ],
        ),
      ),
    ),
  ),
),

image.png

試してないけど、Cardじゃなくても同じようなことが言えるんだろうなあ。

(12/6追加)解決その2

Cardに clipBehavior というパラメータがありそれでも解決できることがわかった。

Clip.antiAliasWithSaveLayer は非常に遅いというのが書いてあるので、ひとまずhardEdgeantiAlias を試してそれぞれの左上の隅を確認してみた。
Macのプレビューアプリを使い拡大してみた結果です。
左からhardEdge, antiAlias, ClipPathを使った例, 何もchildを含めないCardの順です。

image.png

これをみると、ドキュメント通りやはりhardEdgeは荒い。拡大しなくてもその荒さがわかるぐらい。
一方、antiAlias, ClipPathを使った例、この2つはあまり遜色なかった。
どっちでもいいけど手軽さやメンテナンス性を考えるとantiAliasを使う方が圧倒的に良いと考える。

ClipPathを使った実装は、後から見た人はなぜこういう作りにしている?と疑問に思いそうなので。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3