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

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

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

解決済

Androidアプリ作成でのテキスト生成後のテキスト位置

fukumomo
fukumomo

総合スコア10

2回答

0グッド

0クリップ

512閲覧

投稿2022/04/29 06:19

編集2022/04/29 06:41

kotlinでAndroidアプリ作成しており、マッピングアプリを作成しようと思っています。
そこで、ボタンを押してテキストを追加生成したら、そのテキストを移動できるようにしたいと思っています。

テキストの追加と移動はできているのですが、ボタンを押してテキスト生成すると全てのテキスト位置が元に戻ってしまいます。
どうすればボタンを押してもテキストがその位置を維持した状態になりますか?

MainActivity.kt

1import android.os.Bundle 2import android.view.MotionEvent 3import android.view.View 4import android.widget.TextView 5import androidx.appcompat.app.AppCompatActivity 6import com.example.mapping.databinding.ActivityMainBinding 7 8class MainActivity : AppCompatActivity(), View.OnTouchListener{ 9 private lateinit var binding: ActivityMainBinding 10 private var mappingText1 = "abc" 11 private var oldX = 0F 12 private var oldY = 0F 13 private var addId = 1 14 private lateinit var addItems: TextView 15 16 //生成されるテキスト 17 private fun getTextView(addId: Int): TextView { 18 addItems = TextView(this).apply { 19 id = addId 20 text = id.toString() 21 textSize = 50F 22 } 23 return addItems 24 } 25 26 override fun onCreate(savedInstanceState: Bundle?) { 27 super.onCreate(savedInstanceState) 28 binding = ActivityMainBinding.inflate(layoutInflater) 29 val view = binding.root 30 setContentView(view) 31 32 //ボタンを押してテキスト追加 33 binding.button.setOnClickListener{ 34 //テキスト追加時にviewに個別のidを設定 35 binding.constraint.addView(getTextView(addId)) 36 //追加したviewをaddItemsとして、リスナを設定 37 addItems.setOnTouchListener(this) 38 //ボタンを押した後、idの値をプラスしておく 39 addId++ 40 } 41 } 42 43 override fun onTouch(v: View, event: MotionEvent): Boolean { 44 var newX = event.x 45 var newY = event.y 46 47 when (event.action) { 48 MotionEvent.ACTION_MOVE -> { 49 var leftF = v.left + (newX - oldX) 50 var topF = v.top + (newY - oldY) 51 var left = leftF.toInt() 52 var top = topF.toInt() 53 54 v.layout(left, top, left + v.width, top + v.height) 55 return true 56 } 57 } 58 oldX = newX 59 oldY = newY 60 61 return true 62 }

activity_main.xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 xmlns:app="http://schemas.android.com/apk/res-auto" 6 android:id="@+id/constraint" 7 android:layout_width="match_parent" 8 android:layout_height="match_parent" 9 tools:context=".MainActivity"> 10 <Button 11 android:id="@+id/button" 12 android:text="テキスト追加" 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 app:layout_constraintStart_toStartOf="parent" 16 app:layout_constraintEnd_toEndOf="parent" 17 app:layout_constraintBottom_toBottomOf="parent" 18 /> 19</androidx.constraintlayout.widget.ConstraintLayout>

以下のような質問にはグッドを送りましょう

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

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

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答2

1

ベストアンサー

テキストを ConstraintLayout に追加していますが、ConstraintLayout は子ビューに設定された制約 (ボタンの app:layout_constraintStart_toStartOf="parent" など) に基づいてレイアウトを行うので、制約を設定しないと新しいテキストを追加した時にレイアウトのやり直しが起こって、初期位置に戻されてしまうのでしょう。

とりあえず以下のように変更して、テキストに制約を設定すれば期待する動きになると思いますが、本来ならばカスタム ViewGroup を作るべきな気が… (面倒くさいので、お勧めはしません)。

diff

1 // import 追加 2 3+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT 4+import androidx.constraintlayout.widget.ConstraintLayout 5 6 // onCreate メソッドで、テキスト追加時に ConstraintLayout.LayoutParams を設定 7 8- binding.constraint.addView(getTextView(addId)) 9+ val params = ConstraintLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT) 10+ params.leftToLeft = R.id.constraint 11+ params.topToTop = R.id.constraint 12+ params.leftMargin = 0 13+ params.topMargin = 0 14+ binding.constraint.addView(getTextView(addId), params) 15 16 // onTouch メソッドで、テキストの移動は ConstraintLayout.LayoutParams の変更で行う 17 18- v.layout(left, top, left + v.width, top + v.height) 19+ val params = v.layoutParams as ConstraintLayout.LayoutParams 20+ params.leftMargin = left 21+ params.topMargin = top 22+ v.layoutParams = params

投稿2022/04/30 09:48

hoshi-takanori

総合スコア7740

fukumomo👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

fukumomo

2022/05/01 07:02

すごくわかりやすい解説ありがとうございます。 うまく行かない原因も理解できて、無事思っていた通りの動きになりました。 マッピングアプリを作る上での他の良いアプローチ方法が自分では思いつかないので、アドバイス頂いたカスタムViewGroupを作って進めていきたいと思います。

0

すごくわかりやすい解説ありがとうございます。
うまく行かない原因も理解できて、無事思っていた通りの動きになりました。
マッピングアプリを作る上での他の良いアプローチ方法が自分では思いつかないので、アドバイス頂いたカスタムViewGroupを作って進めていきたいと思います。

投稿2022/05/01 06:54

fukumomo

総合スコア10

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

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