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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

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

Q&A

解決済

2回答

3082閲覧

MainActivity以外のクラスからfindViewByIdを実行する方法

m-mega

総合スコア56

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

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

0グッド

0クリップ

投稿2022/03/28 09:47

以前の質問からの続きになります。

実現したいこと

別のクラスでユーザーが動的に変更した矩形の情報(OpenCVの検出領域の情報)を、MainActivityに受け渡したい。

できていること

・OpenCVの検出領域を限定的にする(以前の質問で解決しました。)
・カメラプレビューの上に透明なCanvasを置いて、Canvas上に検出領域となる矩形を描画する
・矩形のサイズ、位置をドラッグ&ドロップで動的に変更できるようにする(現在のコードでは、矩形の中心付近をドラッグすると移動、各辺をドラッグするとドラッグした辺のみ移動する機能を実装できています)

やったこと

下記のサイトを参考に、矩形の描画、ドラッグ&ドロップの機能を実装しました。
ImageViewのドラッグ
Canvasで矩形を描画
Canvasをレイアウトに挿入

また、現在実装には至っていませんが、値の受け渡しについては下記のサイトを参考にしています。
putExtraによる値の受け渡し

現状について

現在の大まかなプロジェクト構成は、下記の通りです。

「MainActivity.kt」
・カメラプレビューを表示
(ユーザーにはカラー映像で検出領域の調整を行なったほしいので、このタイミングではまだOpenCVによる処理は実行されません。設定のみされている状態です。)
・ボタンを押すとIntentで別のアクティビティに遷移します。
(この遷移先のアクティビティに矩形の情報を渡して、限定的な範囲でOpenCVを実行する予定です。)

kotlin

1package jp.gr.java_conf.coskx.targetinggame 2 3import android.Manifest 4import android.annotation.SuppressLint 5import android.content.Intent 6import android.content.pm.PackageManager 7import android.os.Bundle 8import android.util.Log 9import android.view.View 10import android.widget.Button 11import androidx.appcompat.app.AppCompatActivity 12import androidx.appcompat.widget.AppCompatImageView 13import org.opencv.android.CameraBridgeViewBase 14import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2 15import org.opencv.core.CvType 16import org.opencv.core.Mat 17 18class MainActivity : AppCompatActivity(), CvCameraViewListener2 { 19 private var mOpenCvCameraView: CameraBridgeViewBase? = null 20// private var TrimView: AppCompatImageView? = null 21 private var mMat: Mat? = null 22 23 override fun onStart() { 24 super.onStart() 25 var havePermission = true 26 if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { 27 requestPermissions( 28 arrayOf(Manifest.permission.CAMERA), 29 CAMERA_PERMISSION_REQUEST_CODE 30 ) 31 havePermission = false 32 } 33 if (havePermission) { 34 mOpenCvCameraView!!.setCameraPermissionGranted() 35 } 36 } 37 38 override fun onRequestPermissionsResult( 39 requestCode: Int, 40 permissions: Array<String>, 41 grantResults: IntArray 42 ) { 43 if (requestCode == CAMERA_PERMISSION_REQUEST_CODE && grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 44 mOpenCvCameraView!!.setCameraPermissionGranted() 45 } 46 super.onRequestPermissionsResult(requestCode, permissions, grantResults) 47 } 48 49 @SuppressLint("ClickableViewAccessibility") 50 override fun onCreate(savedInstanceState: Bundle?) { 51 super.onCreate(savedInstanceState) 52 setContentView(R.layout.activity_main) 53 54 // ボタンを押したらゲーム画面へ 55 val btnStart :Button = findViewById(R.id.btnStart) // Viewの取得 56 btnStart.setOnClickListener { 57 val intent = Intent(this,GamePlayActivity::class.java) // 遷移元と遷移先の設定 58 startActivity(intent) // 遷移の実行 59 overridePendingTransition(0, 0) // 遷移時のアニメーションを消す 60 } 61 62// TrimView = findViewById<View>(R.id.trim_view) as AppCompatImageView 63 64 // OpenCVの設定 65 System.loadLibrary("opencv_java4") 66 mOpenCvCameraView = findViewById<View>(R.id.camera_view) as CameraBridgeViewBase 67 mOpenCvCameraView!!.setCvCameraViewListener(this) 68 // 画像回転作業負荷を低減するためpreviewの解像度を設定 69 mOpenCvCameraView!!.setMaxFrameSize(960, 720) 70 } 71 72 public override fun onResume() { 73 super.onResume() 74 mOpenCvCameraView!!.enableView() 75 } 76 77 public override fun onDestroy() { 78 super.onDestroy() 79 if (mOpenCvCameraView != null) mOpenCvCameraView!!.disableView() 80 } 81 82 override fun onCameraViewStarted(width: Int, height: Int) { 83 mMat = Mat(height, width, CvType.CV_8UC4) 84 Log.i(TAG, "=================mMatRed列数:${mMat!!.width()} ====================") 85 Log.i(TAG, "=================mMatRed行数:${mMat!!.height()} ====================") 86 } 87 88 override fun onCameraViewStopped() { 89 mMat?.release() 90 } 91 92 override fun onCameraFrame(inputFrame: CameraBridgeViewBase.CvCameraViewFrame): Mat? { 93 // カメラプレビューの各フレームをフルカラーで取得 94 mMat = inputFrame.rgba() 95 return mMat 96 } 97 98 // カメラのパーミッション 99 companion object { 100 private const val TAG = "MainActivity" 101 const val CAMERA_PERMISSION_REQUEST_CODE = 200 102 } 103}

「TrimView.java」
・矩形をCanvas上で描画し、ユーザーのドラッグ&ドロップによって動的に位置、サイズを変更
・activity_main.xmlに記載してレイアウトに挿入
・矩形の座標情報を文字列に変換してレイアウト上のテキストに反映
↑この部分がうまくいっていない状態です。

java

1package jp.gr.java_conf.coskx.targetinggame; 2... 3public class TrimView extends AppCompatImageView { 4 ... 5 private TextView textView; 6 7 public TrimView(Context context, AttributeSet attrs) { 8 super(context, attrs); 9 rect = new Rect(); 10 paint = new Paint(); 11 paint.setColor(0xFF008800); // 線の色 12 paint.setStyle(Paint.Style.STROKE); 13 paint.setStrokeJoin(Paint.Join.ROUND); 14 paint.setStrokeCap(Paint.Cap.ROUND); 15 paint.setStrokeWidth(strokeWidth); // 線の太さ 16 rect.set(firstX, firstY, rect.left + rectW, rect.top + rectH); 17 18 textView = ((jp.gr.java_conf.coskx.targetinggame.MainActivity)context).findViewById(R.id.txtRect); // 矩形のサイズを表示するテキスト 19 } 20 21 @Override 22 protected void onDraw(@NonNull Canvas canvas) { 23 canvas.drawRect(rect, paint); // 描画 24 // キャンバスのサイズ取得 25 canvasW = getWidth(); 26 canvasH = getHeight(); 27 } 28 29 @Override 30 public boolean performClick() { 31 super.performClick(); 32 return true; 33 } 34 35 @Override 36 @SuppressLint("ClickableViewAccessibility") 37 public boolean onTouchEvent(@NonNull MotionEvent event) { 38 ... 39 // 押した場合の処理 40 if (event.getAction() == MotionEvent.ACTION_DOWN) { 41 ... 42 } 43 // ドラッグした場合の処理 44 else if (event.getAction() == MotionEvent.ACTION_MOVE) { 45 ... 46 } 47 // 指を離した場合の処理 48 else if (event.getAction() == MotionEvent.ACTION_UP) { 49 ... 50 // 矩形のサイズをテキストに変換してxmlに反映する 51 String str = "left="+rect.left 52 +"\ntop="+rect.top 53 +"\nright="+rect.right 54 +"\nbottom="+rect.bottom; 55 textView.setText(str); // 矩形のサイズを反映 56 } 57 return true; 58 } 59}

「activity_main.xml」

kotlin

1... 2 <jp.gr.java_conf.coskx.targetinggame.TrimView 3 android:id="@+id/trim_view" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" /> 6... 7 <TextView 8 android:id="@+id/txtRect" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:layout_marginTop="76dp" 12 android:background="#FFFFFF" 13 app:layout_constraintEnd_toEndOf="parent" 14 app:layout_constraintHorizontal_bias="0.498" 15 app:layout_constraintStart_toStartOf="parent" 16 app:layout_constraintTop_toBottomOf="@+id/btnStart" /> 17 18</androidx.constraintlayout.widget.ConstraintLayout>

エラー内容

<「TrimView.java」該当箇所>

java

1textView = ((jp.gr.java_conf.coskx.targetinggame.MainActivity)context).findViewById(R.id.txtRect); // 矩形のサイズを表示するテキスト 2... 3// 矩形のサイズをテキストに変換してxmlに反映する 4 String str = "left="+rect.left 5 +"\ntop="+rect.top 6 +"\nright="+rect.right 7 +"\nbottom="+rect.bottom; 8 textView.setText(str); // 矩形のサイズを反映

<エラー内容>

Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

nullオブジェクトを参照しているとあるので、おそらくfindViewByIdの時点でうまく読み込めていないものと思われます。

わからないこと

レイアウトとして挿入したクラス(TrimView.java)で設定した変数の値を、アクティビティに渡す方法が分かりません。
上記のようにfindViewByIdで読み込んだテキストに値を代入しようとしていますが、現状ではうまくいっていない状態です。

値がテキストに反映できれば、そのテキストをMainActivityで読み込んで、その後「putExtra」で遷移先のアクティビティに値を渡せると考えています。
ですが、非常に効率が悪いようにも感じています。

findViewByIdで実現する方法があればお伺いしたいですが、同時に、より効率的な方法がないかもお尋ねしたいです。

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

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

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

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

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

guest

回答2

0

自己解決

早々にご回答いただきありがとうございました。
ご提案いただいた内容を実装したところ、無事に理想とする動きを実現できました。
お陰様で複数のviewを扱う場合の処理について理解が深まりました。ありがとうございます。

本質問についてご検討いただいた全ての方々に感謝いたします。
また、本質問が同様の疑問を持たれている方の助けになれば幸いです。

投稿2022/03/31 10:05

m-mega

総合スコア56

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

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

0

※コードの動作確認等はしていません。

レイアウト xml に記述したビューのコンストラクタが呼ばれる段階で、同じレイアウト xml に記述されている他の(親・兄弟)ビューが完全に生成されているかどうかは分からないのではないでしょうか。
また、コード的にも、特定のビューが他のビューの存在を固定的に決め打っているのは、良くない傾向に思います。

TrimView で使用しようとしている TextView はコンストラクト時に必要なわけでは無く、単にタッチイベント時にデータを表示するだけのようです。
であれば、 "指を離した場合の処理" を行うリスナを定義し、それを TrimView に設定できるようにすることで、 TrimView が特定の View に依存する形を止めることが出来るのではないでしょうか。

※以下のコードはイメージです。コンパイルエラーは出ていませんが動作確認はしていません。

MainActivity.java

java

1package com.teratail.q_o11p3cl1yt1nyy; 2 3import androidx.appcompat.app.AppCompatActivity; 4 5import android.os.Bundle; 6import android.widget.TextView; 7 8public class MainActivity extends AppCompatActivity { 9 @Override 10 protected void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 setContentView(R.layout.activity_main); 13 14 TextView textView = findViewById(R.id.txtRect); 15 16 TrimView trimView = findViewById(R.id.trim_view); 17 trimView.setOnActionUpListener(rect -> { 18 // 矩形のサイズをテキストに変換してxmlに反映する 19 String str = "left="+rect.left 20 +"\ntop="+rect.top 21 +"\nright="+rect.right 22 +"\nbottom="+rect.bottom; 23 textView.setText(str); // 矩形のサイズを反映 24 }); 25 } 26}

res/layout/activity_main.xml

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:app="http://schemas.android.com/apk/res-auto" 5 xmlns:tools="http://schemas.android.com/tools" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context=".MainActivity"> 9 10 <com.teratail.q_o11p3cl1yt1nyy.TrimView 11 android:id="@+id/trim_view" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:text="Hello World!" 15 app:layout_constraintBottom_toTopOf="@id/txtRect" 16 app:layout_constraintLeft_toLeftOf="parent" 17 app:layout_constraintRight_toRightOf="parent" 18 app:layout_constraintTop_toTopOf="parent" /> 19 20 <TextView 21 android:id="@+id/txtRect" 22 android:layout_width="match_parent" 23 android:layout_height="wrap_content" 24 app:layout_constraintBottom_toBottomOf="parent" 25 app:layout_constraintLeft_toLeftOf="parent" 26 app:layout_constraintRight_toRightOf="parent" 27 app:layout_constraintTop_toBottomOf="@id/trim_view" /> 28 29</androidx.constraintlayout.widget.ConstraintLayout>

TrimView.java

java

1package com.teratail.q_o11p3cl1yt1nyy; 2 3import android.content.Context; 4import android.graphics.Rect; 5import android.util.AttributeSet; 6import android.view.MotionEvent; 7 8import androidx.annotation.*; 9import androidx.appcompat.widget.AppCompatImageView; 10 11public class TrimView extends AppCompatImageView { 12 interface OnActionUpListener { 13 void onActionUp(Rect rect); 14 } 15 16 public TrimView(Context context, @Nullable AttributeSet attrs) { 17 super(context, attrs); 18 } 19 20 private Rect rect; 21 22 private OnActionUpListener onActionUpListener; 23 24 void setOnActionUpListener(OnActionUpListener listener) { 25 this.onActionUpListener = listener; 26 } 27 28 //@Override 29 //@SuppressLint("ClickableViewAccessibility") 30 public boolean onTouchEvent(@NonNull MotionEvent event) { 31 // 押した場合の処理 32 if (event.getAction() == MotionEvent.ACTION_DOWN) { 33 } 34 // ドラッグした場合の処理 35 else if (event.getAction() == MotionEvent.ACTION_MOVE) { 36 } 37 // 指を離した場合の処理 38 else if (event.getAction() == MotionEvent.ACTION_UP) { 39 if(onActionUpListener != null) onActionUpListener.onActionUp(rect); 40 } 41 return true; 42 } 43}

投稿2022/03/28 10:44

編集2022/03/28 11:03
jimbe

総合スコア12632

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

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

m-mega

2022/03/31 10:09

申し訳ございません、誤って自己解決としてしまいました。 jimbe様には以前からご教授いただいており、いつも大変感謝しております。 以後気をつけますので、何卒ご理解ください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問