18
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Flutterで Widgetをくり抜く 方法

Posted at

Flutter では ClipRect, ClipOval を使用して Widget を Clip ことができます。

矩形切り取り

new ClipRect(
  child: new Align(
    alignment: Alignment.topCenter,
    heightFactor: 0.5,
    child: new Image.network(userAvatarUrl),
  ),
)

オーバル切り取り

new ClipOval(
  child: new Align(
    color: Colors.black,
    alignment: Alignment.topCenter,
    child: new Image.network(userAvatarUrl),
  ),
)

くり抜くには、ClipPathCustomClipper を使用することで可能です。

ClipPath(
  clipper: InvertedCircleClipper(),
    child: Container(
    color: Color.fromRGBO(0, 0, 0, 0.8),
  ),
),
class InvertedCircleClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    return Path()
      // くり抜き
      ..addOval(
        Rect.fromCircle(
          center: Offset(size.width / 2, size.height / 2),
          radius: size.width * 0.25,
        ),
      )
      // 全体描画
      ..addRect(Rect.fromLTWH(0.0, 0.0, size.width, size.height))
      ..fillType = PathFillType.evenOdd;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

こんな感じのことができます。

device-2018-10-01-180722.png

全体ソースコード

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: SafeArea(
        child: Container(
          constraints: BoxConstraints.expand(),
          color: Colors.amber,
          child: Column(
            children: <Widget>[
              Expanded(
                child: Stack(
                  children: <Widget>[
                    Container(
                      color: Colors.green,
                      alignment: Alignment.center,
                      child: Image.asset(
                        'images/lake.jpg',
                        fit: BoxFit.cover,
                      ),
                    ),
                    new ClipOval(
                      child: new Align(
                        alignment: Alignment.topCenter,
                        heightFactor: 0.5,
                        child: new Image.network(userAvatarUrl),
                      ),
                    ),
                    ClipPath(
                      clipper: InvertedCircleClipper(),
                      child: Container(
                        color: Color.fromRGBO(0, 0, 0, 0.8),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class InvertedCircleClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    return Path()
      // くり抜き
      ..addOval(
        Rect.fromCircle(
          center: Offset(size.width / 2, size.height / 2),
          radius: size.width * 0.25,
        ),
      )
      // 全体描画
      ..addRect(Rect.fromLTWH(0.0, 0.0, size.width, size.height))
      ..fillType = PathFillType.evenOdd;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

参考)

18
12
1

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
18
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?