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

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

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

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

Android Studio

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

Q&A

解決済

1回答

2021閲覧

Android Studio:Dialogの表示について

sato_shoma

総合スコア12

Java

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

Android Studio

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

0グッド

0クリップ

投稿2022/03/21 06:07

編集2022/03/21 09:04

前提

Android StudioでJavaを使ってメモ帳アプリを作っています。作成してメモを削除するときに、本当に削除するか確認するダイアログを出したいのですがjava.lang.IllegalStateExceptionが出て、うまくいきません。

実現したいこと

  • ダイアログの実装

発生している問題・エラーメッセージ

E/AndroidRuntime: FATAL EXCEPTION: main Process: jp.halo_sf.haloint, PID: 22128 java.lang.IllegalStateException: FragmentManager has not been attached to a host. at androidx.fragment.app.FragmentManager.enqueueAction(FragmentManager.java:1880) at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:329) at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:294) at androidx.fragment.app.DialogFragment.show(DialogFragment.java:260) at jp.halo_sf.haloint.RecyclerViewAdapter.lambda$onBindViewHolder$0(RecyclerViewAdapter.java:42) at jp.halo_sf.haloint.RecyclerViewAdapter$$ExternalSyntheticLambda0.onClick(Unknown Source:0) at android.view.View.performClick(View.java:7463) at android.view.View.performClickInternal(View.java:7440) at android.view.View.access$3600(View.java:825) at android.view.View$PerformClick.run(View.java:28414) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:8240) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:979)

該当のソースコード

MainActivity.java

1 2package jp.halo_sf.haloint; 3 4import android.database.Cursor; 5import android.os.Bundle; 6 7import androidx.appcompat.app.AppCompatActivity; 8import androidx.recyclerview.widget.LinearLayoutManager; 9import androidx.recyclerview.widget.RecyclerView; 10 11public class MainActivity extends AppCompatActivity { 12 private DatabaseHelper _helper; 13 private static RecyclerView rvNote; 14 private static RecyclerViewAdapter adapter; 15 16 @Override 17 protected void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.activity_main); 20 21 //DatabaseHelperの生成処理。 22 _helper = new DatabaseHelper(MainActivity.this); 23 24 //RecyclerViewの設定。 25 rvNote = findViewById(R.id.rvNote); 26 rvNote.setLayoutManager(new LinearLayoutManager(MainActivity.this)); 27//DataBaseからデータを取得。 28 Cursor cursor = _helper.getData(); 29 NoteManager noteManager = new NoteManager(); 30 while (cursor.moveToNext()) { 31 noteManager.addNoteItem(String.valueOf(cursor.getInt(0)), cursor.getString(1), cursor.getString(2)); 32 } 33 noteManager.addToMapData(); 34 cursor.close(); 35 adapter = new RecyclerViewAdapter(noteManager.getNoteItems()); 36 rvNote.setAdapter(adapter); 37 } 38

RecyclerViewAdapter.java

1package jp.halo_sf.haloint; 2 3import androidx.fragment.app.FragmentActivity; 4 5public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerListViewHolder> { 6 @Override 7 public void onBindViewHolder(@NonNull RecyclerListViewHolder holder, int position) { 8 holder._tvTitle.setText(titles.get(position)); 9 holder._tvText.setText(texts.get(position)); 10 11 holder._iBtnDeleteL.setOnClickListener(view -> { 12 DialogFragmentCheckingDelete dialogFragment = new DialogFragmentCheckingDelete(); 13//エラー文に記載されている箇所。 14 dialogFragment.show(new FragmentActivity().getSupportFragmentManager(), 15"DialogFragmentCheckingDelete"); 16 }); 17 } 18} 19 20

試したこと

getSupportFragmentManagerをFragmentActivityをインスタンス化して取得しているからだと思い、MainActivityにダイアログを表示するメソッドを記入し、そこで処理を行ってみましたが全く状況が変わらなかったので元に戻しました。
おそらくgetFragmentManagerが関係していると思うのですが…何か分かることがあれば、些細な事でも良いのでお教えいただけますと幸いです。何卒宜しくお願い致します。

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

Android Studio Bumblebee | 2021.1.1 Patch 2
Build #AI-211.7628.21.2111.8193401, built on February 17, 2022
ランタイム・バージョン: 11.0.11+9-b60-7590822 amd64
VM: OpenJDK 64-Bit Server VM by Oracle Corporation
Windows 10 10.0
GC: G1 Young Generation, G1 Old Generation
Memory: 1280M
Cores: 8
Registry: external.system.auto.import.disabled=true
Non-Bundled Plugins: dev.polek.adbwifi (1.2.4), org.jetbrains.kotlin (211-1.6.10-release-923-AS7442.40)

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

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

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

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

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

hoshi-takanori

2022/03/21 08:02

> MainActivityにダイアログを表示するメソッドを記入 でいけると思いますけど。(まさか new MainActivity() してそのメソッドを呼び出したとか?)
sato_shoma

2022/03/21 08:25 編集

そのまさかです。本当に未熟なものですみません。私もそれが問題なのではないかと思い、requireActivity();等のメソッドを試しても見たのですがこのメソッドがどうもRecyclerView.Adapterでは使えないみたいで…もし良ければ、どうすれば良いのかお教え願えませんでしょうか?
hoshi-takanori

2022/03/21 08:34

RecyclerViewAdapter に MainActivity の参照を持たせれば良いかと。 (具体的なコードを知りたければ、MainActivity で RecyclerViewAdapter を生成してるあたりのコードをお示しください。)
sato_shoma

2022/03/21 09:05

遅くなってしまってすみません。今コードを追加したのでご覧くださると幸いです。
guest

回答1

0

ベストアンサー

new FragmentActivity().getSupportFragmentManager()

先のご質問でも少し書きましたが、ここでも new FragmentActivity() は意味がありません。
根本として、 アクティビティはアプリのコードが new で作っても動作しないモノです。
アクティビティはただ作れば良いものでは無く、 Android OS と結びついて初めて動作する存在です。ですのでアクティビティが必要であれば、既に動作しているアプリのアクティビティを何とか取得する必要があります。
ついでに、フラグメントマネージャはアクティビティ毎(ついでにフラグメント毎にも)にありますので、どのアクティビティ(もしくはフラグメント)でも良いという訳にもいきません。

ご質問のコードの場合は、Adapter 内でクリック時の処理を行うよりも、アクティビティにクリックされたことを伝えて後の処理を任せるほうが Adapter の役割としては適当に思います。

java

1public class MainActivity extends AppCompatActivity { 2 @Override 3 protected void onCreate(Bundle savedInstanceState) { 4//略 5 adapter = new RecyclerViewAdapter(noteManager.getNoteItems()); 6 adapter.setDeleteListener((view, position) -> { 7 DialogFragmentCheckingDelete dialogFragment = new DialogFragmentCheckingDelete(); 8 dialogFragment.show(getSupportFragmentManager(), "DialogFragmentCheckingDelete"); 9 }); 10 rvNote.setAdapter(adapter); 11//略 12 } 13}

java

1public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerListViewHolder> { 2//略 3 interface DeleteListener { 4 void onDelete(View view, int position); 5 } 6 7 private DeleteListener deleteListener; 8 void setDeleteListener(DeleteListener deleteListener) { 9 this.deleteListener = deleteListener; 10 } 11 12 @Override 13 public void onBindViewHolder(@NonNull RecyclerListViewHolder holder, int position) { 14 holder._tvTitle.setText(titles.get(position)); 15 holder._tvText.setText(texts.get(position)); 16 holder._iBtnDeleteL.setTag(position); 17 } 18 19 public class RecyclerListViewHolder extends RecyclerView.ViewHolder { 20 final TextView _tvTitle; 21 final TextView _tvText; 22 final Button _iBtnDeleteL; 23 24 public NoteViewHolder(View itemView) { 25 super(itemView); 26 _tvTitle= itemView.findViewById(R.id.tvNoteTitle); 27 _tvText= itemView.findViewById(R.id.tvNoteText); 28 _iBtnDeleteL= itemView.findViewById(R.id.dtnDelete); 29 _iBtnDeleteL.setOnClickListener(view -> { 30 if(deleteListener != null) deleteListener.onDelete(view, (int)_iBtnDeleteL.getTag()); 31 }); 32 } 33 } 34//略

投稿2022/03/21 09:09

編集2022/03/21 11:53
jimbe

総合スコア12612

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

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

sato_shoma

2022/03/21 09:40 編集

jimbeさん、またもご回答くださりありがとうございます。お恥ずかしい話、まだアンドロイドアプリにおけるnewというものがいまいちどころか全然理解できていません。 >アクティビティはアプリのコードが new で作っても動作しないモノです。アクティビティはただ作れば良いものでは無く、 Android OS と結びついて初めて動作する存在です。 とのことでしたが、この場合、newはいつ使えるのでしょうか?newを使って良い場面とダメな場面について、よろしければご教授願えませんでしょうか?
jimbe

2022/03/21 10:07

new はオブジェクトを作るものですので、 java 言語としてはいつでも使えます。 ただ、Android として new で作ってもそのままでは動かない特殊(?)なものがあるということで、その1つがアクティビティです。 他にどんなものがあるのかは、それらを列挙した資料というのは見たことがありませんのでお答えし兼ねます。 目安的には、アクティビティやコンテキストから get~ で取得するような (フラグメントマネージャとか) は大抵 new で作っても動かないと思いますが、逆の現象として例外的に動くもの(コンストラクタのパラメータにアクティビティやコンテキストを指定するものとか)もあるかもしれません。 何かのクラスやメソッドを初めて使おうという場合は、ドキュメントやサンプルをよく読んで、new するのか何かから get するのかを確認しておくと良いでしょう。
sato_shoma

2022/03/21 10:14 編集

ご返答本当にありがとうございます。自分なりに考えてみたのであっているか確かめていただけると幸いです。 今回の場合でいうと、getSupportFragmentManager();を、ダイアログを表示するアクティビティ上で行わないと、正しいFragmentManagerが取得できないため、ダイアログがうます表示できないということであっていますか? また、「試したこと」に書いた >getSupportFragmentManagerをFragmentActivityをインスタンス化して取得しているからだと思い、MainActivityにダイアログを表示するメソッドを記入し、そこで処理を行ってみましたが全く状況が変わらなかった というのはメソッドを呼び出すときにnew MainActivity();をしてしまっているため、今表示しているMainActivity(MainActivity1とする)とは別のMainActivityが作られてしまいそこで処理を行っても、MainActivity1には反映されないため、表示ができないということであっていますか?
sato_shoma

2022/03/21 11:37 編集

何度も質問してすみません。これで大丈夫だと思ったのですが、実はダイアログにRecyclerViewのpositionを引き渡したいのです。positionがonBindHolder内なら取得できるのですが、MainActivityからはおそらく取得できません。なので、onBindHolderのフィールドにpositionを保存してgetter経由で取得しようと思ったのですが、setonClickListener();の中でpositionを取得しなければいけません。しかし、このメソッドのなかにはすでにdeleteLitenerが入っているのでどうすれば良いのか、さっぱり分かりません。どうかお教え願いませんでしょうか?
jimbe

2022/03/21 11:36 編集

> 今回の場合でいうと、getSupportFragmentManager();を、ダイアログを表示するアクティビティ上で行わないと、正しいFragmentManagerが取得できないため、ダイアログがうまく表示できないということであっていますか? 合っています。 > new MainActivity();をしてしまっているため、今表示しているMainActivity(MainActivity1とする)とは別のMainActivityが作られてしまいそこで処理を行っても、MainActivity1には反映されないため、表示ができないということであっていますか? ほぼ合っています。 より正確に言うならば、new MainActivity() として作成したオブジェクトは回答に書きましたように"アクティビティとしての意味は無い"モノですので、それを用いて何かをしようとしても大方は(ご経験されているようにどこかで例外が発生するなどして)処理が出来ないと思います。 たまたま例外が発生しないような処理をしたとして「表示ができない(されない)」という結果になります。
jimbe

2022/03/21 11:38

> 実はダイアログにRecyclerViewのpositionを引き渡したいのです。 回答のコードでは DeleteListener として OnCLickListener を流用(?) していますが、専用リスナを作ってパラメータとして渡すのがスマートに思います。 回答を編集します。
sato_shoma

2022/03/21 11:40

返信ありがとうございます!インスタンス化についてだいぶ理解を深められました。jimbeさんのおかげです。本当に申し訳ないのですが、上の質問についてもご回答いただけると幸いです。
sato_shoma

2022/03/21 12:01

回答編集、本当にありがとうございました。今回は、この質問に丁寧にご回答くださり、根本的な原因を教えてくださったjinbeさんをベストアンサーとさせていただきました。コメントしてくださったhoshi-takanoriさん、この質問を呼んでくださった多くの方々にも感謝を述べたいと思います。本当にありがとうございました。また分からないことがあれば質問させていただくと思うので、これからも何卒宜しくお願い致します。
jimbe

2022/03/21 12:01

ViewHolder を前のご質問から持ってきましたので view の id とかイロイロ違うかもしれませんが、必要なのは コンストラクタでの setOnClickListener の部分だけです。 DeleteListener.onDelete に View パラメータを入れていますが、使う予定が無ければ(恐らく使うことは無いと思いますが^^;) potision だけにしても大丈夫でしょう。
sato_shoma

2022/03/21 12:33

ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問