質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

0回答

1509閲覧

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

active_vintage

総合スコア0

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2022/09/22 15:44

編集2022/09/23 16:43

前提

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

*本質問はさまざまな方のご意見を聞きたいため以下サイトでも同様の質問を投稿しております。
https://qiita.com/active_vintage/questions/a828f3c2d8def17c65b5

実現したいこと

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

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

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

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

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

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

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

該当のソースコード

文字数の制限によりimportの部分をimport 〜で全て割愛しています。
必要そうな部分は全てimportしています。
またそのほかの部分も一部割愛しています。ご了承ください。

MainActivity.kt

kotlin

1package com.example.rouletteimage 2 3import4 5class MainActivity : AppCompatActivity() { 6 override fun onCreate(savedInstanceState: Bundle?) { 7 super.onCreate(savedInstanceState) 8 setContentView(R.layout.activity_main) 9 10 val editTextTextPersonName = findViewById<EditText>(R.id.editTextTextPersonName) 11 val editTextNumber1 = findViewById<EditText>(R.id.editTextNumber1) 12 val editTextNumber2 = findViewById<EditText>(R.id.editTextNumber2) 13 val button = findViewById<Button>(R.id.button) 14 15 button.setOnClickListener { 16 val intent = Intent(this, RouletteScreen::class.java) 17 18 val etText1 = editTextTextPersonName.text.toString() 19 val etText2 = editTextNumber1.text.toString() 20 val etText3 = editTextNumber2.text.toString() 21 22 intent.putExtra("key1",etText1) 23 intent.putExtra("key2",etText2) 24 intent.putExtra("key3",etText3) 25 startActivity(intent) 26 finish() 27 } 28 } 29}

MyView.kt

kotlin

1package com.example.rouletteimage 2 3import4 5class MyView(context: Context?, attrs: AttributeSet?) : 6 View(context, attrs) { 7 var paint: Paint 8 private val Paint1 = Paint() 9 private val Paint2 = Paint() 10 private val Paint3 = Paint() 11 private val Paint4 = Paint() 12 private val Paint5 = Paint() 13 private val Paint6 = Paint() 14 private val Paint7 = Paint() 15 private val Paint8 = Paint() 16 private val Paint9 = Paint() 17 private val Paint10 = Paint() 18 private val Paint11 = Paint() 19 20 21 @SuppressLint("DrawAllocation") 22 override fun onDraw(canvas: Canvas) { 23 // 背景、半透明 24 canvas.drawColor(Color.argb(0, 0, 0, 0)) 25 26 // 円 27 paint.color = Color.argb(255, 0, 0, 0) 28 paint.strokeWidth = 5f 29 paint.isAntiAlias = true 30 paint.style = Paint.Style.STROKE 31 32 // 分岐 33 if(height >= width){ 34 // 円 35 // (x1,y1,r,paint) 中心x1座標, 中心y1座標, r半径 36 canvas.drawCircle((width/2).toFloat(), (height/2).toFloat(), (width/2.5).toFloat(), paint) 37 38 // 各項目 39 val rectf = RectF((width/10).toFloat(), (height/2-2*width/5).toFloat(), (9*width/10).toFloat(), (height/2+2*width/5).toFloat()) 40 41 Paint1.color = Color.argb(195, 233, 58, 36) 42 canvas.drawArc(rectf, -90F, 36F, true, Paint1) 43 Paint2.color = Color.argb(195, 234, 97, 25) 44 canvas.drawArc(rectf, -54F, 36F, true, Paint2) 45 Paint3.color = Color.argb(195, 252, 202, 0) 46 canvas.drawArc(rectf, -18F, 36F, true, Paint3) 47 Paint4.color = Color.argb(195, 184, 198, 1) 48 canvas.drawArc(rectf, 18F, 36F, true, Paint4) 49 Paint5.color = Color.argb(195, 58, 149, 42) 50 canvas.drawArc(rectf, 54F, 36F, true, Paint5) 51 Paint6.color = Color.argb(195, 10, 151, 114) 52 canvas.drawArc(rectf, 90F, 36F, true, Paint6) 53 Paint7.color = Color.argb(195, 24, 158, 151) 54 canvas.drawArc(rectf, 126F, 36F, true, Paint7) 55 Paint8.color = Color.argb(195, 89, 113, 157) 56 canvas.drawArc(rectf, 162F, 36F, true, Paint8) 57 Paint9.color = Color.argb(195, 104, 68, 126) 58 canvas.drawArc(rectf, 198F, 36F, true, Paint9) 59 Paint10.color = Color.argb(195, 224, 61, 114) 60 canvas.drawArc(rectf, 234F, 36F, true, Paint10) 61 } 62 else{ 63 // 円 64 canvas.drawCircle((width/2).toFloat(), (height/2).toFloat(), (height/2.5).toFloat(), paint) 65 66 // 各項目 67 val rectf = RectF((width/2-2*height/5).toFloat(), (height/10).toFloat(), (width/2+2*height/5).toFloat(), (9*height/10).toFloat()) 68 69 Paint1.color = Color.argb(195, 233, 58, 36) 70 canvas.drawArc(rectf, -90F, 36F, true, Paint1) 71 Paint2.color = Color.argb(195, 234, 97, 25) 72 canvas.drawArc(rectf, -54F, 36F, true, Paint2) 73 Paint3.color = Color.argb(195, 252, 202, 0) 74 canvas.drawArc(rectf, -18F, 36F, true, Paint3) 75 Paint4.color = Color.argb(195, 184, 198, 1) 76 canvas.drawArc(rectf, 18F, 36F, true, Paint4) 77 Paint5.color = Color.argb(195, 58, 149, 42) 78 canvas.drawArc(rectf, 54F, 36F, true, Paint5) 79 Paint6.color = Color.argb(195, 10, 151, 114) 80 canvas.drawArc(rectf, 90F, 36F, true, Paint6) 81 Paint7.color = Color.argb(195, 24, 158, 151) 82 canvas.drawArc(rectf, 126F, 36F, true, Paint7) 83 Paint8.color = Color.argb(195, 89, 113, 157) 84 canvas.drawArc(rectf, 162F, 36F, true, Paint8) 85 Paint9.color = Color.argb(195, 104, 68, 126) 86 canvas.drawArc(rectf, 198F, 36F, true, Paint9) 87 Paint10.color = Color.argb(195, 224, 61, 114) 88 canvas.drawArc(rectf, 234F, 36F, true, Paint10) 89 } 90 } 91 init { 92 paint = Paint() 93 } 94}

RouletteScreen.kt

kotlin

1package com.example.rouletteimage 2 3import4 5class RouletteScreen : AppCompatActivity() { 6 7 override fun onCreate(savedInstanceState: Bundle?) { 8 super.onCreate(savedInstanceState) 9 setContentView(R.layout.activity_roulette_screen) 10 11 val button2 = findViewById<Button>(R.id.button2) 12 val button3 = findViewById<Button>(R.id.button3) 13 val button4 = findViewById<Button>(R.id.button4) 14 val text3 = findViewById<TextView>(R.id.textView3) 15 16 val etText1 = intent.getStringExtra("key1") 17 val etText2 = intent.getStringExtra("key2") 18 val etText3 = intent.getStringExtra("key3") 19 20 text3.text = etText1 21 button3.isEnabled = false 22 button2.setOnClickListener { 23 button2.isEnabled = false 24 button3.isEnabled = true 25 } 26 button3.setOnClickListener { 27 button2.isEnabled = true 28 button3.isEnabled = false 29 } 30 button4.setOnClickListener { 31 val intent = Intent(this, MainActivity::class.java) 32 startActivity(intent) 33 finish() 34 } 35 } 36}

activity_main.xml

文字数制限により割愛します。

activity_roulette_screen.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 tools:context=".RouletteScreen"> 8 9 //単純なButtonやTextViewは省略 10 11 <FrameLayout 12 android:id="@+id/fl" 13 android:layout_width="wrap_content" 14 android:layout_height="0dp" 15 android:layout_marginTop="24dp" 16 app:layout_constraintBottom_toTopOf="@+id/button2" 17 app:layout_constraintEnd_toEndOf="parent" 18 app:layout_constraintHorizontal_bias="0.5" 19 app:layout_constraintStart_toStartOf="parent" 20 app:layout_constraintTop_toBottomOf="@+id/textView3"> 21 22 <com.example.rouletteimage.MyView 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 app:layout_constraintBottom_toBottomOf="parent" 26 app:layout_constraintLeft_toLeftOf="parent" 27 app:layout_constraintRight_toRightOf="parent" 28 app:layout_constraintTop_toTopOf="parent" /> 29 30 </FrameLayout> 31 32 33</androidx.constraintlayout.widget.ConstraintLayout>

現状のコードでは以下のように動きます
MainActivity
RouletteScreen

試したこと

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

補足情報(FW/ツールのバージョンなど)

Android Studio Chipmunk | 2021.2.1 Patch 1
Kotlin 1.7.0
macOS monterey 12.5.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ak.n

2022/09/22 23:54

様々な作り方がありますので、他の方のご異論もあるかと思いますが、 私なら、ルーレットそのものを定義する Roulette.kt でルーレットのクラスを作り、分割数や比率をメンバ変数に設定する SetAttr メソッドや、角度を引数に与えて描画する Draw メソッドなどを準備し(ルーレットの回転は、drawArc の引数で角度が指定できます)、MainActivity や View からこのルーレットクラスのインスタンスを操作する Roulette.SetAttr(...), Roulette.Draw(...) というような作り方がわかりやすいのではないかと思います。 for ループの中でルーレットを回転しようとしても、他のイベントが処理できなくなってしまうのでシステムが固まります。スレッドとタイマーを使って一定間隔(100msなど)で関数を呼び出すようにしその関数の中で角度の値を変えていくように作ります。あとはクリックなどのイベントを拾ってタイマーを起動させたり停止させたり、というイメージです。
active_vintage

2022/09/23 16:37

ak.nさん ご回答ありがとうございます。 ルーレットクラスのインスタンスを操作する方法を参考にさせていただきます さまざまなご指摘、ご提案ありがとうございました。
active_vintage

2022/09/23 16:37

1T2R3M4さん ご指摘ありがとうございます 対応させていただきます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問