Flutter Tips💡 – InkWellのRippleエフェクトがはみ出す問題

自作ボタンのリップルエフェクトがはみ出してしまう

ボタンをFlatButtonやRaisedButtonではなく、InkWellを使用して自作した場合、

ボタンに色をつけるとスプラッシュカラーが反映されず、

また角丸をつけたデザインにするとリップルエフェクトがはみ出してしまう。

以下の3つのコードは全て上のGIFように、エフェクトが最背面に表示されたようになってしまう。

// InkWellを親ウィジェットに
InkWell(
  splashColor: _Styles.splashColor,
  onTap: () {},
  child: Container(  // Containerに角丸とボタンカラーを付与
    decoration: BoxDecoration(
      borderRadius: _Styles.borderRadius,
      color: _Styles.buttonColor,
    ),
    padding: _Styles.padding,
    child: const Text('自爆ボタン'),
  ),
),

// -> InkWellが親ウィジェットにあるので、なんとなくエフェクトが再背面に表示されるのはわかる
// Containerを親ウィジェットに
// 角丸とボタンカラーを付与
Container(
  decoration: BoxDecoration(
    borderRadius: _Styles.borderRadius,
    color: _Styles.buttonColor,
  ),
  child: InkWell(  // InkWellを子ウィジェットに
    splashColor: _Styles.splashColor,
    onTap: () {},
    child: Padding(
      padding: _Styles.padding,
      child: const Text('自爆ボタン'),
    ),
  ),
),

// -> 子ウィジェットは親ウィジェットの前面に表示されるはずな気もするが、これもNG。
// ClipRRectで子ウィジェットを切り取る
ClipRRect(
  borderRadius: _Styles.borderRadius,
  child: Container(  // ClipRRectに色指定はできないのでここで
    color: _Styles.buttonColor,
    child: InkWell(
      splashColor: _Styles.splashColor,
      onTap: () {},
      child: Padding(
        padding: _Styles.padding,
        child: const Text('自爆ボタン'),
      ),
    ),
  ),
),

// -> ボタン自体の切り取りはやってくれるが、リップルエフェクトはやっぱりダメ。

解決策

Materialウィジェットでラップして、

ボタンカラーと角丸はMaterialウィジェットに付与すると解決する。

また、角丸を付ける場合は「clipBehavior」プロパティに”Clip.antiAlias”を指定する。

Material(
  borderRadius: _Styles.borderRadius,
  color: _Styles.buttonColor,
  clipBehavior: Clip.antiAlias,  // 角丸がいらない場合は不要
  child: InkWell(
    splashColor: _Styles.splashColor,
    onTap: () {},
    child: Container(
      padding: _Styles.padding,
      child: const Text('自爆ボタン'),
    ),
  ),
),

コレで解決!