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

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

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

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

Kotlin

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

Q&A

解決済

1回答

1050閲覧

DialogFlagmentからActivityのメソッドを使うとヌルポが起きる。

hood

総合スコア351

Android

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

Kotlin

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

0グッド

0クリップ

投稿2019/02/27 21:36

###DialogFlagmentからActivityのメソッドを使うとヌルポが起きる。

私はアラートダイアログを出現させたときactivityの他のボタンを押せなくしたく、ダイアログを出現させたらfindViewById<Button>.isEnabledでfalse、ダイアログのOKボタンを押したらfindViewById<Button>.isEnabledでtrueでもとに戻る処理を実装したいと思いました。

kotlin

1//アラートダイアログ 2class Alert : DialogFragment() { 3・・・・ 4 /*ボタンリスナ*/ 5 inner class DialogButtonClickListener : DialogInterface.OnClickListener{ 6 //クリック時に呼び出される。l 7 override fun onClick(dialog: DialogInterface?, which: Int) { 8 val a = TitleActivity() 9 a.onAlertClick(which) 10 } 11 } 12・・・・ポジティブボタンに、このリスナーをつける。 13}

kotlin

1//Alertを使う、activity 2class TitleActivity : ..., DialogInterface.OnClickListener{ 3・・・ 4//dialogから使われるメソッド 5 fun onAlertClick(which: Int){ 6 when(which){ 7 DialogInterface.BUTTON_POSITIVE -> {//okを押されたら、ボタンを使えるようにする。 8 findViewById<Button>(R.id.button_start).isEnabled=true //しかしヌルポ 9 } 10 } 11 } 12・・・ 13} 14

しかし、タイトルにも書いたようにこのメソッドを使おうとすると、findViewById<Button(R.id.button_start).isEnabled=trueでヌルポが起きてしまいます。ですのでfindViewByIdだけの問題ではなく、TitleActivityの変数にアクセスできないということだと思います。

また、findViewByIdだけではありません。
soundpoolを使い、音を鳴らそうとするとそれもヌルポになってしまいます。

kotlin

1 fun onAlertClick(which: Int){ 2 when(which){ 3 DialogInterface.BUTTON_POSITIVE -> { 4 soundPool!!.play(soundGo, 1.0f, 1.0f, 0, 0, 1f) //ヌルポ 5 } 6 } 7 }

ひるがえって、このactivityでは、もう一つ別のダイアログもあるのですが、そちらではactivityに継承させたDialogInterface.OnClickListeneronClickメソッドをoverrideし、それをDialogから使っています。そうするとなぜか上記のようなヌルポは起きません。

kotlin

1//もう一つのダイアログ。 2class StoryConfirm : DialogFragment() { 3・・・ 4 inner class DialogButtonClickListener : DialogInterface.OnClickListener{ 5 override fun onClick(dialog: DialogInterface?, which: Int) { 6 val a = activity 7 if (a is DialogInterface.OnClickListener) { 8 a.onClick(dialog, which) 9 } 10 } 11 } 12・・・ポジティブボタンに、このリスナーをつける。 13}

kotlin

1//上にでてきたのと同じactivity 2class TitleActivity : ..., DialogInterface.OnClickListener{ 3・・・ 4//Alertから使われるメソッド 5 fun onAlertClick(which: Int){ 6 when(which){ 7 DialogInterface.BUTTON_POSITIVE -> {//okを押されたら、ボタンを使えるようにする。 8 findViewById<Button>(R.id.button_start).isEnabled=true //しかしヌルポ 9 } 10 } 11 } 12 //DialogInterface.OnClickListenerのonClickをoverrideしたもの。StoryConfirmから使う 13 override fun onClick(dialog: DialogInterface?, which: Int) { 14 when(which){ 15 DialogInterface.BUTTON_POSITIVE->{ 16 soundPool!!.play(soundGo, 1.0f, 1.0f, 0, 0, 1f)//使える 17 findViewById<Button>(R.id.button_start).isEnabled=true//使える 18 } 19 } 20  } 21・・・ 22} 23

この違いはなぜ起きるのでしょう?DialogInterface.OnClickListeneronClickoverrideしただけで、それ以外に違いはないように見えるのですが・・・またどうすればAlertから使われるメソッドのほうでヌルポを回避できるのか・・・

どうかアドバイスいただけたら幸いです...

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

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

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

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

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

guest

回答1

0

自己解決

理屈はわからないのですが、以前の質問でいただいた回答を参考にリスナーを定義して、実装するやりかたをとったらできました。

ActvityをhogeActivity()とインスタンス化するのは、よくないのかもしれない・・・・基本はactivityでインスタンスを確保。そして、それからインターフェースを使い、if(is)とやる。

投稿2019/02/27 23:36

編集2019/02/27 23:40
hood

総合スコア351

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

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

kakajika

2019/02/28 00:28 編集

Activityのインスタンスを自分で生成することはNGです。OSが用意してくれたものを利用する必要があります。 Kotlinではactivityと省略されてしまっていて少し分かりにくいですが、実際にはFragmentのgetActivity()というメソッドを呼んでいます。これによりFragmentがattachされているActivityのインスタンスが取得できるわけです。 https://developer.android.com/reference/android/app/Fragment.html#getActivity() また、インターフェースを用いてメソッドを呼び出すのはあくまで密結合になるのを防止するためで、必須ではありません。特定のActivity専用のDialogFragmentであるなら、if (a is TitleActivity)で十分でしょう。
hood

2019/02/28 00:52 編集

コメントありがとうございます! >Activityのインスタンスを自分で生成することはNG やっぱりそうだったんですね・・・確かに普通に生成すると、onCreateとか意味わからなくなりますものね・・・これからは同じ轍は踏まないようにしたいです・・・ >if (a is TitleActivity) この式で、ああっ!そういうことかっ!!と腑に落ちました。 isでactivityをTitleActivityにSmart Castsするという方法ですね・・・前回の回答の「activityのインスタンス」はSmart Casts前提のものだったと分かりました。 全く思いつきませんでした・・・本当の本当に、脱帽の二文字です。 すでに解決済みにもかかわらずアドバイスをくださり、もやっとしていた部分を晴らすことができました。返す返すありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問