目次

目次

【Android】Canvas APIの使い方

chiaki.kyui
chiaki.kyui
最終更新日2022/12/14 投稿日2022/12/14

この記事はレコチョク Advent Calendar 2022の14日目の記事となります。

はじめに

はじめまして、秦基博さんと日向坂46さんに日々癒しと元気をいただいている休井です。
株式会社レコチョクでAndroidの開発をしています。

最近はJetpack Composeを使用してUI作成をすることが多いのですが、何となく難しそうで触れてこなかったCanvas APIについて、実際に使ってみながらご紹介したいと思います。

Canvas APIについて

Androidでは、Jetpack ComposeというUIツールキットが提供されており、宣言的にUIを作成することができます。
CanvasはそのJetpack Composeに含まれるAPIで、画面内の位置(座標)を用いてレイアウトの設定を行うことができるので、かなり自由度高くカスタムレイアウトを作成することができます。

基本的な使い方

  1. 線を引く drawLine() を使用します。
    startendで線の開始と終了を指定して線を引くことができます。
    @Composable
    fun DrawLine() {
    Canvas(
        modifier = Modifier
            .fillMaxSize()
    ) {
        val width = size.width
        val height = size.height
        drawLine(
            color = Color.Black,
            start = Offset.Zero,
            end = Offset(width, height),
            strokeWidth = 5F
        )
    }
    }
    

  2. 四角形を描く
    drawRect()を使用します。
    topLeftで描画位置を決め、sizeで大きさを指定して四角形を描くことができます。

    @Composable
    fun DrawRect() {
    Canvas(
        modifier = Modifier
            .fillMaxSize()
    ) {
        val width = size.width
        val height = size.height
        drawRect(
            color = Color.Black,
            topLeft = Offset(width / 3, height / 3),
            size = Size(width / 3, height / 3)
        )
    }
    }
    
    角丸の四角形にしたい場合は、 drawRoundRect()を使いcornerRadiusに丸の半径を設定します。
    @Composable
    fun DrawRoundRect() {
    Canvas(
        modifier = Modifier
            .fillMaxSize()
    ) {
        val width = size.width
        val height = size.height
        drawRoundRect(
            color = Color.Black,
            topLeft = Offset(width / 3, height / 3),
            size = Size(width / 3, height / 3),
            cornerRadius = CornerRadius(x = 100F, y = 100F)
        )
    }
    }
    

  3. 円を描く
    drawCircle()を使用します。 centerで描画位置を決め、radiusで半径を設定して円を描くことができます。

    @Composable
    fun DrawCircle() {
    Canvas(
        modifier = Modifier
            .fillMaxSize()
    ) {
        val width = size.width
        val height = size.height
        drawCircle(
            color = Color.Black,
            radius = 400F,
            center = Offset(width / 2, height / 2)
        )
    }
    }
    
    また、楕円を描きたい場合は、 drawOval()を使用します。
    topLeftで描画位置を決め、sizeで大きさを設定して楕円を描くことができます。
    @Composable
    fun DrawOval() {
    Canvas(
        modifier = Modifier
            .fillMaxSize()
    ) {
        val width = size.width
        val height = size.height
        drawOval(
            color = Color.Black,
            topLeft = Offset(width / 4, height / 3),
            size = Size(width = width / 2, height = height / 5)
        )
    }
    }
    

  4. 弧を描く
    drawArc()を使用します。
    startAngleで開始位置(0Fが3時の方向)を決め、sweepAngleで弧の角度を設定して弧を描くことができます。
    また、 useCentertrueにすると、扇型に描画することができます。

    @Composable
    fun DrawArc() {
    Canvas(
        modifier = Modifier
            .fillMaxSize()
    ) {
        val width = size.width
        drawArc(
            color = Color.Black,
            startAngle = 0F,
            sweepAngle = 90F,
            useCenter = true,
            size = Size(width = width / 2, height = width / 2)
        )
        drawArc(
            color = Color.Black,
            startAngle = 0F,
            sweepAngle = 90F,
            useCenter = false,
            size = Size(width = width / 2, height = width / 2),
            style = Stroke(width = 5F),
            topLeft = Offset(0F, width / 2)
        )
    }
    }
    

  5. 点を描く
    drawPoints()を使用します。
    pointsで描きたい点の位置をリストで指定して点を描くことができます。
    また、 pointModeで描き方、capで点の形を設定できます。

    @Composable
    fun DrawPoints() {
    Canvas(
        modifier = Modifier
            .fillMaxSize()
    ) {
        val height = size.height
        drawPoints(
            points = listOf(
                Offset(300F, height / 2),
                Offset(500F, height / 2),
                Offset(700F, height / 2),
                Offset(900F, height / 2),
                Offset(1100F, height / 2),
                ),
            pointMode = PointMode.Points,
            color = Color.Black,
            strokeWidth = 50F,
            cap = StrokeCap.Square
        )
    }
    }
    

  6. パスを決めて描く
    drawPath()を使用します。
    pathを作成しdrawPath()に渡すことで、作成したpathに色を付けることができます。

    @Composable
    fun DrawPath() {
    Canvas(
        modifier = Modifier
            .fillMaxSize()
    ) {
        val width = size.width
        val height = size.height
        val path = Path()
        path.moveTo(width / 2, height / 3) // pathの開始位置
        path.lineTo(width / 2, height / 2) // 開始位置→(width / 2, height / 2)
        path.lineTo(width, height / 3) // (width / 2, height / 2)→(width, height / 3)
        drawPath(
            path = path,
            color = Color.Black
        )
    }
    }
    

使ってみた

Canvasでできることと使い方の基本について確認できたので、単純なアナログ時計のレイアウトを描いてみました。

chiaki.kyui

目次