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

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

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

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

Android Studio

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

Kotlin

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

受付中

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

active_vintage
active_vintage

総合スコア0

canvas

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

Android Studio

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

Kotlin

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

0回答

0評価

0クリップ

231閲覧

投稿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

package com.example.rouletteimage import 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.putExtra("key1",etText1) intent.putExtra("key2",etText2) intent.putExtra("key3",etText3) startActivity(intent) finish() } } }

MyView.kt

kotlin

package com.example.rouletteimage import 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

kotlin

package com.example.rouletteimage import 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

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

activity_roulette_screen.xml

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"> //単純なButtonやTextViewは省略 <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>

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

試したこと

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

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

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

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

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さん ご指摘ありがとうございます 対応させていただきます

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

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

canvas

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

Android Studio

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

Kotlin

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