🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

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

Android

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

Android Studio

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

Q&A

解決済

2回答

17597閲覧

Android 他クラスから特定のアクティビティのメソッドを呼びたい

sekaikan_ozaki

総合スコア65

Java

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

Android

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

Android Studio

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

0グッド

1クリップ

投稿2019/09/18 05:25

PCスペック
Windows10 HOME 64bit
メモリ 32GB
プロセッサ Intel Core i7-8700CPU 3.20GHz
Android Studio 3.4.1(最新ver)
デモ用端末(XPERIA OS:7.0 API 24)

androidでお絵描きアプリを作っています.
ネットの情報を参考に,開発を進めているのですが,どうしても解決しない問題があります.

タイトルのように,他クラスから特定のアクティビティのメソッドを呼べないところで詰まっています.

現状,下のコードのように,「アクティビティ画面」+「viewを継承したOekakiクラス」の2つで構成しています.

画面上で,指でなぞった部分が着色され,線が残るような挙動になっています.

ここで,スマホ画面から指を離した際に,MainActivityクラスで記述したインスタンスメソッドを呼ぶためには,OekakiクラスのタッチイベントのMotionEvent.ACTION_UPに,任意のコードを書けばよいのですが,そのためにはMainActivityクラスのインスタンスをnewし直さなければなりません.
しかし,MainActivityクラス内では,ほかにも色んな変数やインスタンスメソッドがあり,新しいMainActivityインスタンスを作ってしまうことで,変数の中身が空っぽになってしまい,都合が悪いです.

試したこと
OekakiクラスをMainActivityの内部クラスにしようとしました.が,レイアウトファイルと上手く紐づけすることができず,エラーが頻発してしまい,うまくいきませんでした・・・

新しくインスタンスを作らない方法で,MainActivityのメソッドを呼ぶ方法はありませんでしょうか?

↓MainActivity.java

java

1 2public class MainActivity extends AppCompatActivity { 3 4private Oekaki oekaki; 5 6 @Override 7 protected void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.activity_main); 10 11 oekaki= findViewById(R.id.view); 12 13//その他記述あり 14 15 16} 17

↓Oekaki.java

java

1public class Oekaki extends View { 2 private Paint paint; 3 private Path path; 4 5 //====================================================================================== 6 //-- コンストラクタ 7 //====================================================================================== 8 public Oekaki(Context context) { 9 this(context, null); 10 11 } 12 //====================================================================================== 13 //-- コンストラクタ 14 //====================================================================================== 15 //レイアウトファイルからビューを初期化 16 public Oekaki(Context context, AttributeSet attrs) { 17 super(context, attrs); 18 19 //-- 初期化 20 //- Path関連 21 path = new Path(); 22 //- Paint関連 23 paint = new Paint(); 24 paint.setColor(Color.argb(150, 255, 0, 255)); 25 paint.setStyle(Paint.Style.STROKE);// 描画設定を'線'に設定 26 paint.setStrokeJoin(Paint.Join.ROUND); 27 paint.setStrokeCap(Paint.Cap.ROUND); 28 paint.setAntiAlias(true);// アンチエイリアスの適応 29 paint.setStrokeWidth(80);// 線の太さ 30 } 31 32 33 //====================================================================================== 34 //-- 描画メソッド 35 //====================================================================================== 36 @Override 37 protected void onDraw(Canvas canvas) { 38 canvas.drawPath(path, paint);// Pathの描画 39 } 40 41 //====================================================================================== 42 //-- タッチイベント 43 //===================================================================================== 44 @Override 45 public boolean onTouchEvent(MotionEvent event) { 46 float x = event.getX(); 47 float y = event.getY(); 48 49 switch (event.getAction()) { 50 case MotionEvent.ACTION_DOWN://- 画面をタッチしたとき 51 path.moveTo(x, y);// 始点を設定 52 invalidate();// 再描画 53 break; 54 case MotionEvent.ACTION_MOVE://- タッチしながら指をスライドさせたとき 55 path.lineTo(x, y);// 移動先の追加 56 invalidate();// 再描画 57 break; 58 case MotionEvent.ACTION_UP://- 画面から指を離したとき 59 path.lineTo(x, y);// 移動先の追加 60 invalidate();// 再描画 61 62 63 ※ここでMainActivityのメソッドを呼びたい 64 65 66 break; 67 } 68 return true; 69 } 70 71 //====================================================================================== 72 //-- 削除メソッド 73 //====================================================================================== 74 public void clear(){ 75 path.reset(); 76 invalidate(); 77 } 78 79 80 }

↓activity.main.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<android.support.constraint.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 android:id="@+id/constraintLayout" 9 tools:context=".MainActivity"> 10 11 12 <view 13 android:id="@+id/view" 14 class="com.example.app.Oekaki" 15 android:layout_width="0dp" 16 android:layout_height="0dp" 17 app:layout_constraintBottom_toBottomOf="parent" 18 app:layout_constraintLeft_toLeftOf="parent" 19 app:layout_constraintRight_toRightOf="parent" 20 app:layout_constraintTop_toTopOf="parent" /> 21 22 23</android.support.constraint.ConstraintLayout> 24 25 26 27 28

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

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

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

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

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

guest

回答2

0

そのためにはMainActivityクラスのインスタンスをnewし直さなければなりません.

これと同様の発想に至った質問も数多く見られますが、これは絶対にやってはならないアンチパターンです。ActivityはあくまでAndroidのOS管理下でのみ生成されるもので、ユーザーのコードではnewしてはいけません。

「呼び出したいMainActivityのメソッド」を、Oekakiクラス内に記述したinterfaceのメソッドとして宣言してみてはどうでしょうか。そして、MainActivityではそのinterfaceをimplements(実装)する形とします。

例えば、MainActivityにあるint型の変数を返すgetIntValue()というメソッドがあったならば、次のようにできるでしょう。

MainActivity.java

java

1public class MainActivity extends AppCompatActivity implements Oekaki.Listener { 2 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.activity_main); 7 8 oekaki= findViewById(R.id.view); 9 oekaki.setListener(this); 10 } 11 12 (中略) 13 14 // getIntValue()の実装 15 @Override 16 int getIntValue() { 17 return intValue; // MainActivityが持っているint型の変数を返す 18 } 19}

Oekaki.java

java

1public class Oekaki extends View { 2 3 Listener mListener; 4 5  (中略) 6 7 void setListener(Listener listener) { 8 mListener = listener; 9 } 10 11 @Override 12 public boolean onTouchEvent(MotionEvent event) { 13 14 15 switch (event.getAction()) { 16 case MotionEvent.ACTION_UP://- 画面から指を離したとき 17 path.lineTo(x, y);// 移動先の追加 18 invalidate();// 再描画 19 20 21 int n = mListener.getIntValue(); // MainActivityに実装したgetIntValue()を呼び出せる 22 23 24 break; 25 } 26 return true; 27 } 28 29 interface Listener { 30 int getIntValue(); 31 // 他にもMainActivityに実装するメソッドを羅列していく 32 } 33}

他にもMainActivityから得たい情報があれば、そのメソッドをOekaki.Listenerの中に足していけば要領は同じです。

投稿2019/09/18 09:22

keicha_hrs

総合スコア6768

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

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

sekaikan_ozaki

2019/09/19 01:22

ありがとうございます. アンチパターンなのだと分かり,勉強になりました. 解決案も考えてくださり,有難いです. 実は,自己解決に至れたので,自己解決のところに結果を記述したいと思います. ありがとうございました.
guest

0

自己解決

Oekakiクラスで,MainActivityの現インスタンスを取得できたことにより解決しました.

以下がコードです.

java

1public class MainActivity extends AppCompatActivity { 2 3private Oekaki oekaki; 4private static MainActivity instance = null; 5 6 @Override 7 protected void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.activity_main); 10 11instance = this; 12 13 oekaki= findViewById(R.id.view); 14 15//その他記述あり 16} 17 18 19public static MainActivity getInstance() {//インスタンスを取得 20 return instance; 21 } 22 23 24}

java

1 2import static パッケージ名.MainActivity.getInstance; 3 4 5public class Oekaki extends View { 6 private Paint paint; 7 private Path path; 8 9 //====================================================================================== 10 //-- コンストラクタ 11 //====================================================================================== 12 public Oekaki(Context context) { 13 this(context, null); 14 15 } 16 //====================================================================================== 17 //-- コンストラクタ 18 //====================================================================================== 19 //レイアウトファイルからビューを初期化 20 public Oekaki(Context context, AttributeSet attrs) { 21 super(context, attrs); 22 23 //-- 初期化 24 //- Path関連 25 path = new Path(); 26 //- Paint関連 27 paint = new Paint(); 28 paint.setColor(Color.argb(150, 255, 0, 255)); 29 paint.setStyle(Paint.Style.STROKE);// 描画設定を'線'に設定 30 paint.setStrokeJoin(Paint.Join.ROUND); 31 paint.setStrokeCap(Paint.Cap.ROUND); 32 paint.setAntiAlias(true);// アンチエイリアスの適応 33 paint.setStrokeWidth(80);// 線の太さ 34 } 35 36 37 //====================================================================================== 38 //-- 描画メソッド 39 //====================================================================================== 40 @Override 41 protected void onDraw(Canvas canvas) { 42 canvas.drawPath(path, paint);// Pathの描画 43 } 44 45 //====================================================================================== 46 //-- タッチイベント 47 //===================================================================================== 48 @Override 49 public boolean onTouchEvent(MotionEvent event) { 50 float x = event.getX(); 51 float y = event.getY(); 52 53 switch (event.getAction()) { 54 case MotionEvent.ACTION_DOWN://- 画面をタッチしたとき 55 path.moveTo(x, y);// 始点を設定 56 invalidate();// 再描画 57 break; 58 case MotionEvent.ACTION_MOVE://- タッチしながら指をスライドさせたとき 59 path.lineTo(x, y);// 移動先の追加 60 invalidate();// 再描画 61 break; 62 case MotionEvent.ACTION_UP://- 画面から指を離したとき 63 path.lineTo(x, y);// 移動先の追加 64 invalidate();// 再描画 65 66 67 ※ここでMainActivityのメソッドを呼びたい 68 69getInstance().メソッド名();//MainActivityのメソッドが呼べた 70 71 72 break; 73 } 74 return true; 75 } 76 77 //====================================================================================== 78 //-- 削除メソッド 79 //====================================================================================== 80 public void clear(){ 81 path.reset(); 82 invalidate(); 83 } 84 85 86 }

投稿2019/09/19 01:27

sekaikan_ozaki

総合スコア65

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問