search
LoginSignup
@active_vintage
Q&A

【Android】ルーレットを回転させたい!!!

解決したいこと

AndroidStudioでルーレットを自分で作成できるスマホアプリをつくっています。
ルーレットの元となる円グラフのような画像を回転させる方法などがわかりません。
解決方法を教えて下さい。

使用環境
Android Studio Chipmunk | 2021.2.1 Patch 1
Kotlin 1.7.0
macOS monterey 12.5.1

発生している問題・エラー

現状、以下の3つのktファイルと2つのXMLファイルによる実装を考えています。
考えている機能に関して()中に示します。

1,MainActivity.kt(ルーレット内に入れたい項目とその比率の入力画面)
2,MyView.kt(1で得られた値からルーレットの元となる円グラフを作成する(onDrawないでCanvasを用いています))
3,RouletteScreen.kt(2で得られた円グラフをボタンによって回転させる)
4,MainActivity.xml
5,RouletteScreen.xml

以下に詳細な問題を示します

1,円グラフのような画像を出力させる方法がわかりません

MainActivity.ktからどのように値を受け取りMyView.ktに反映させればいいのかがわかりません。
そもそも、このような場合別ファイルにClassを作って良いのでしょうか?

2,円グラフのような画像ができたとして、どのように回転させればいいかわかりません。

RouletteScreen.ktで円グラフを表示し、さらにその中のkt内で回転の制御をしたいです。
回転の制御についてfor文などでMyView.ktでできる円グラフの画像の描画初期位置を動かして回転させてるように見せるのか、RouletteScreen.ktで画像として保存された円グラフを回転させるのがいのでしょうか?
他に方法があれば教えていただきたいです。

該当するソースコード

MainActivity.kt

package com.example.rouletteimage

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val editTextTextPersonName = findViewById<EditText>(R.id.editTextTextPersonName)
        val editTextNumber1 = findViewById<EditText>(R.id.editTextNumber1)
        val editTextNumber2 = findViewById<EditText>(R.id.editTextNumber2)
        val button = findViewById<Button>(R.id.button)

        button.setOnClickListener {
            val intent = Intent(this, RouletteScreen::class.java)

            val etText1 = editTextTextPersonName.text.toString()
            val etText2 = editTextNumber1.text.toString()
            val etText3 = editTextNumber2.text.toString()

            //intent変数をつなげる(第一引数はキー,第二引数は渡したい変数)
            intent.putExtra("key1",etText1)
            intent.putExtra("key2",etText2)
            intent.putExtra("key3",etText3)
            startActivity(intent)
            finish()
        }
    }
}

MyView.kt

package com.example.rouletteimage

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View

class MyView(context: Context?, attrs: AttributeSet?) :
    View(context, attrs) {
    var paint: Paint
    private val Paint1 = Paint()
    private val Paint2 = Paint()
    private val Paint3 = Paint()
    private val Paint4 = Paint()
    private val Paint5 = Paint()
    private val Paint6 = Paint()
    private val Paint7 = Paint()
    private val Paint8 = Paint()
    private val Paint9 = Paint()
    private val Paint10 = Paint()
    private  val Paint11 = Paint()

    @SuppressLint("DrawAllocation")
    override fun onDraw(canvas: Canvas) {
        // 背景、半透明
        canvas.drawColor(Color.argb(0, 0, 0, 0))

        // 円
        paint.color = Color.argb(255, 0, 0, 0)
        paint.strokeWidth = 5f
        paint.isAntiAlias = true
        paint.style = Paint.Style.STROKE

        // 分岐
        if(height >= width){
            // 円
            // (x1,y1,r,paint) 中心x1座標, 中心y1座標, r半径
            canvas.drawCircle((width/2).toFloat(), (height/2).toFloat(), (width/2.5).toFloat(), paint)

            // 各項目
            val rectf = RectF((width/10).toFloat(), (height/2-2*width/5).toFloat(), (9*width/10).toFloat(), (height/2+2*width/5).toFloat())

            Paint1.color = Color.argb(195, 233, 58, 36)
            canvas.drawArc(rectf, -90F, 36F, true, Paint1)
            Paint2.color = Color.argb(195, 234, 97, 25)
            canvas.drawArc(rectf, -54F, 36F, true, Paint2)
            Paint3.color = Color.argb(195, 252, 202, 0)
            canvas.drawArc(rectf, -18F, 36F, true, Paint3)
            Paint4.color = Color.argb(195, 184, 198, 1)
            canvas.drawArc(rectf, 18F, 36F, true, Paint4)
            Paint5.color = Color.argb(195, 58, 149, 42)
            canvas.drawArc(rectf, 54F, 36F, true, Paint5)
            Paint6.color = Color.argb(195, 10, 151, 114)
            canvas.drawArc(rectf, 90F, 36F, true, Paint6)
            Paint7.color = Color.argb(195, 24, 158, 151)
            canvas.drawArc(rectf, 126F, 36F, true, Paint7)
            Paint8.color = Color.argb(195, 89, 113, 157)
            canvas.drawArc(rectf, 162F, 36F, true, Paint8)
            Paint9.color = Color.argb(195, 104, 68, 126)
            canvas.drawArc(rectf, 198F, 36F, true, Paint9)
            Paint10.color = Color.argb(195, 224, 61, 114)
            canvas.drawArc(rectf, 234F, 36F, true, Paint10)
        }
        else{
            // 円
            canvas.drawCircle((width/2).toFloat(), (height/2).toFloat(), (height/2.5).toFloat(), paint)

            // 各項目
            val rectf = RectF((width/2-2*height/5).toFloat(), (height/10).toFloat(), (width/2+2*height/5).toFloat(), (9*height/10).toFloat())

            Paint1.color = Color.argb(195, 233, 58, 36)
            canvas.drawArc(rectf, -90F, 36F, true, Paint1)
            Paint2.color = Color.argb(195, 234, 97, 25)
            canvas.drawArc(rectf, -54F, 36F, true, Paint2)
            Paint3.color = Color.argb(195, 252, 202, 0)
            canvas.drawArc(rectf, -18F, 36F, true, Paint3)
            Paint4.color = Color.argb(195, 184, 198, 1)
            canvas.drawArc(rectf, 18F, 36F, true, Paint4)
            Paint5.color = Color.argb(195, 58, 149, 42)
            canvas.drawArc(rectf, 54F, 36F, true, Paint5)
            Paint6.color = Color.argb(195, 10, 151, 114)
            canvas.drawArc(rectf, 90F, 36F, true, Paint6)
            Paint7.color = Color.argb(195, 24, 158, 151)
            canvas.drawArc(rectf, 126F, 36F, true, Paint7)
            Paint8.color = Color.argb(195, 89, 113, 157)
            canvas.drawArc(rectf, 162F, 36F, true, Paint8)
            Paint9.color = Color.argb(195, 104, 68, 126)
            canvas.drawArc(rectf, 198F, 36F, true, Paint9)
            Paint10.color = Color.argb(195, 224, 61, 114)
            canvas.drawArc(rectf, 234F, 36F, true, Paint10)
        }
    }
    init {
        paint = Paint()
    }
}

RouletteScreen.kt

package com.example.rouletteimage

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class RouletteScreen : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_roulette_screen)

        val button2 = findViewById<Button>(R.id.button2)
        val button3 = findViewById<Button>(R.id.button3)
        val button4 = findViewById<Button>(R.id.button4)
        val text3 = findViewById<TextView>(R.id.textView3)

        val etText1 = intent.getStringExtra("key1")
        val etText2 = intent.getStringExtra("key2")
        val etText3 = intent.getStringExtra("key3")

        text3.text = etText1
        button3.isEnabled = false
        button2.setOnClickListener {
            button2.isEnabled = false
            button3.isEnabled = true
        }
        button3.setOnClickListener {
            button2.isEnabled = true
            button3.isEnabled = false
        }
        button4.setOnClickListener {
            val intent = Intent(this, MainActivity::class.java)
            startActivity(intent)
            finish()
        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="@string/textView"
        android:textColor="#000000"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/editTextTextPersonName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:autofillHints=""
        android:ems="10"
        android:hint="@string/itemName"
        android:inputType="textPersonName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <EditText
        android:id="@+id/editTextNumber1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:autofillHints=""
        android:ems="10"
        android:hint="@string/items"
        android:inputType="number"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editTextTextPersonName" />

    <EditText
        android:id="@+id/editTextNumber2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:autofillHints=""
        android:ems="10"
        android:hint="@string/itemRate"
        android:inputType="number"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editTextNumber1" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="@string/button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editTextNumber2" />

</androidx.constraintlayout.widget.ConstraintLayout>

activity_roulette_screen.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".RouletteScreen">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="@string/text2"
        android:textColor="#000000"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="@string/text3"
        android:textColor="#000000"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="100dp"
        android:text="@string/button2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/button3"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="100dp"
        android:text="@string/button3"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/button2" />

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"
        android:text="@string/button4"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent" />

    <FrameLayout
        android:id="@+id/fl"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginTop="24dp"
        app:layout_constraintBottom_toTopOf="@+id/button2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView3">

        <com.example.rouletteimage.MyView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </FrameLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

現状このままですと以下のようになります
スクリーンショット 2022-09-23 0.20.29.png
スクリーンショット 2022-09-23 0.20.40.png

自分で試したこと

さまざま調べましたがjavaでの記載などが多く理解できませんでした。

0
2
Answer

ViewではなくImageViewからsetDrawableを呼んで

RotateDrawableを指定すればよいのでは?

0
ご提案ありがとうございます。
他サイトにて同様の質問をしていますが、
そこではRoulette.kt などのルーレットのクラスを作り、その中のインスタンスを他ktファイルで操作する方法をご提案いただきました。

Kotlinやクラスの扱いに関してかなり拙い部分がありますので@largetownskyさんからみてどちらが有効だと考えられますでしょうか。
ご回答いただければ幸いです。

以下、他サイトへの質問のリンクです。
https://teratail.com/questions/uoc502h6uy2cmo

急ぎならともかく、両方作ってどちらが自分に合っているか試してみるのが、一番勉強になると思いますよ。

勉強目的ではなく急ぎで作るなら、回転操作専用のRotateDrawableの方がシンプルかつ高速に動作しそうなので、こちらから試しますが。

0
助言ありがとうございます
ご提案いただいた通りRotateDrawableの方で一度作成してみたいと思います
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login