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

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

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

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

Android Studio

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

Kotlin

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

Q&A

解決済

1回答

1568閲覧

時刻に合わせてダイアログ内のImageViewを非表示にしたい

kbayashi

総合スコア18

Android

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

Android Studio

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

Kotlin

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

0グッド

0クリップ

投稿2020/04/04 12:46

編集2020/04/04 23:55

現在todoアプリを作成しています。
##実現したいこと
タスク編集画面のリマインダーボタンを押すと、自作したダイアログを表示することができ、現在時刻に合わせて、朝の6時から18時までの間ならreminderNightButtonを表示し、reminderMorningButtonを非表示に、それ以外の時刻なら表示・非表示を逆にするという処理を作成したいのですが、問題があります。
##問題
TaskAddActivityでreminderButton.setOnClickListenerでダイアログのインスタンスを取得した後、dialog.reminderMorningButton.visibility = View.GONEで現在時刻に合わせてボタンを非表示にするという処理を書いていますが、そこでjava.lang.IllegalStateException: dialog.reminderMorningButton must not be nullとなり強制終了してしまいます。

TaskAddActivity

kotlin

1class TaskAddActivity : AppCompatActivity(), ReminderDialog.Listener{ 2 3 override fun reminderUp(date: Date) { 4 val calendar = Calendar.getInstance() 5 calendar.time = date 6 setAlarmManager(calendar) 7 Toast.makeText( 8 this, "リマインダーをセット", 9 Toast.LENGTH_SHORT 10 ).show() 11 } 12 private lateinit var realm: Realm 13 var taskId:Long? = null 14 private var taskTitle:String? = null 15 16 override fun onCreate(savedInstanceState: Bundle?) { 17 super.onCreate(savedInstanceState) 18 setContentView(R.layout.activity_task_add) 19 realm = Realm.getDefaultInstance() 20 21 taskId = intent?.getLongExtra("task_id", -1L) 22 23 val task = realm.where<Task>().equalTo("id", taskId).findFirst() 24 titleEdit.setText(task?.title) 25 taskEditText.setText(task?.detail) 26 taskTitle = task?.title 27 28 29 //リマインダーダイアログを呼び出す 30 reminderButton.setOnClickListener { 31 var dialog = ReminderDialog() 32 val now = Calendar.getInstance() 33 //時刻が夜の6時より前だったら太陽ボタンを消す 34 if(now.get(Calendar.HOUR) <= 18 && now.get(Calendar.HOUR) >= 6){ 35 dialog.reminderMorningButton.visibility = View.GONE 36 }else{ 37 dialog.reminderNightButton.visibility = View.GONE 38 } 39 dialog.show(supportFragmentManager, "alert_dialog") 40 } 41 42 } 43

ReminderDialog

kotlin

1class ReminderDialog : DialogFragment(), 2 TimePickerDialog.OnTimeSetListener, com.wdullaer.materialdatetimepicker.date.DatePickerDialog.OnDateSetListener 3{ 4 interface Listener{ 5 fun reminderUp(date:Date) 6 } 7 private var listener: Listener? = null 8 private var dialogDateTime: String? = null 9 private var dateTime:Date? = null 10 11 //フラグメントがアクティビティから呼び出されたとき 12 override fun onAttach(context: Context) { 13 super.onAttach(context) 14 when(context){ 15 is Listener -> listener = context 16 } 17 } 18 19 //日付選択後時刻選択ダイアログを呼び出す 20 override fun onDateSet( 21 view: com.wdullaer.materialdatetimepicker.date.DatePickerDialog?, 22 year: Int, 23 monthOfYear: Int, 24 dayOfMonth: Int 25 ) { 26 val c = Calendar.getInstance() 27 c.set(year, monthOfYear, dayOfMonth) 28 val date = DateFormat.format("yyyy/MM/dd", c).toString() 29 dialogDateTime = date 30 showTimePickerDialog(date) 31 } 32 33 //時刻を選択 34 override fun onTimeSet(view: TimePickerDialog?, hourOfDay: Int, minute: Int, second: Int) { 35 val time = "%1$02d:%2$02d".format(hourOfDay, minute) 36 dialogDateTime += " ${time}" 37 dateTime = dialogDateTime?.toDate() 38 39 } 40 41 42 43 //時刻選択ダイアログ 44 fun showTimePickerDialog(date:String) { 45 val now = Calendar.getInstance() 46 val dpd = TimePickerDialog.newInstance( 47 this, 48 now.get(Calendar.HOUR), 49 now.get(Calendar.MINUTE)+1, 50 now.get(Calendar.SECOND), 51 false 52 ) 53 var test = now.get(Calendar.YEAR).toString() + "/0" + ((now.get(Calendar.MONTH)+1).toString()) + "/" + now.get(Calendar.DAY_OF_MONTH).toString() 54 Log.d("HOUR","${now.get(Calendar.HOUR)}") 55 //指定された日付が現在日付ならば現在時刻の五分以降より前の時刻は選択させない 56 if(date == test) { 57 dpd.setMinTime(Timepoint(now.get(Calendar.HOUR),(now.get(Calendar.MINUTE)+1))) 58 } 59 60 dpd.show(fragmentManager!!, "aaaa") 61 } 62 63 64 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { 65 66 //ダイアログのインスタンス取得 67 val dialog:Dialog = Dialog(activity!!) 68 //タイトルバーなしのダイアログを表示 69 dialog.window?.requestFeature(Window.FEATURE_NO_TITLE) 70 //フルスクリーンでダイアログを表示 71 dialog.window?.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 72 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN) 73 //レイアウト指定 74 dialog.setContentView(R.layout.reminder_layout) 75 val now = Calendar.getInstance() 76 77 78 //背景色を透明に 79 dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) 80 dialog.window?.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 81 82 83 //日付選択ダイアログ呼び出し 84 dialog.reminderCustomButton.setOnClickListener { 85 val dpd = com.wdullaer.materialdatetimepicker.date.DatePickerDialog.newInstance( 86 this, 87 now.get(Calendar.YEAR), // Initial year selection 88 now.get(Calendar.MONTH), // Initial month selection 89 now.get(Calendar.DAY_OF_MONTH) // Inital day selection 90 ) 91 dpd.minDate = now 92 dpd.show(fragmentManager!!, "Datepickerdialog") 93 } 94 95 //保存ボタンを押したら通知を指定時間にセット 96 dialog.saveButton.setOnClickListener { 97 when{ 98 dateTime != null ->{ 99 val setDateTime = dateTime 100 if(setDateTime !=null) 101 listener?.reminderUp(setDateTime) 102 } 103 } 104 } 105 106 dialog.cancelButton.setOnClickListener { 107 dialog.cancel() 108 } 109 110 return dialog 111 } 112 113 //文字をDateに変換 114 private fun String.toDate(pattern: String = "yyyy/MM/dd HH:mm"): Date?{ 115 return try { 116 SimpleDateFormat(pattern).parse(this) 117 }catch (e: IllegalArgumentException){ 118 return null 119 }catch (e: ParseException){ 120 return null 121 } 122 } 123} 124

reminder_layout.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:id="@+id/linearLayout" 6 android:layout_width="match_parent" 7 android:layout_height="wrap_content" 8 android:layout_margin="16dp" 9 android:background="@drawable/shape_rounded_corners_5dp"> 10 11 <ImageView 12 android:id="@+id/reminderMorningButton" 13 android:layout_width="91dp" 14 android:layout_height="91dp" 15 android:background="@drawable/image_view_maru" 16 android:scaleType="fitCenter" 17 app:layout_constraintBottom_toTopOf="@+id/linearLayout2" 18 app:layout_constraintEnd_toEndOf="parent" 19 app:layout_constraintStart_toEndOf="@+id/reminderCustomButton" 20 app:layout_constraintTop_toBottomOf="@+id/textView" 21 app:srcCompat="@drawable/ic_wb_sunny_black_24dp" /> 22 23 <ImageButton 24 android:id="@+id/reminderCustomButton" 25 android:layout_width="91dp" 26 android:layout_height="91dp" 27 android:layout_marginStart="24dp" 28 android:layout_marginTop="8dp" 29 android:background="@drawable/image_view_maru" 30 android:scaleType="centerCrop" 31 app:layout_constraintStart_toEndOf="@+id/reminderNightButton" 32 app:layout_constraintTop_toBottomOf="@+id/textView" 33 app:srcCompat="@drawable/ic_watch_later_black_24dp" /> 34 35 <ImageButton 36 android:id="@+id/reminderNightButton" 37 android:layout_width="91dp" 38 android:layout_height="91dp" 39 android:layout_marginStart="24dp" 40 android:layout_marginTop="8dp" 41 android:background="@drawable/image_view_maru" 42 android:scaleType="centerCrop" 43 app:layout_constraintStart_toStartOf="parent" 44 app:layout_constraintTop_toBottomOf="@+id/textView" 45 app:srcCompat="@drawable/ic_brightness_3_black_24dp" /> 46 47 <TextView 48 android:id="@+id/textView" 49 android:layout_width="0dp" 50 android:layout_height="wrap_content" 51 android:background="@drawable/text_view_rounded" 52 android:text="リマインダー追加" 53 android:textColor="#000000" 54 android:textSize="35sp" 55 android:textStyle="bold" 56 app:layout_constraintEnd_toEndOf="parent" 57 app:layout_constraintStart_toStartOf="parent" 58 app:layout_constraintTop_toTopOf="parent" /> 59 60 <LinearLayout 61 android:id="@+id/linearLayout2" 62 android:layout_width="match_parent" 63 android:layout_height="0dp" 64 android:layout_marginTop="16dp" 65 android:orientation="horizontal" 66 app:layout_constraintEnd_toEndOf="parent" 67 app:layout_constraintStart_toStartOf="parent" 68 app:layout_constraintTop_toBottomOf="@+id/reminderCustomButton"> 69 70 <Button 71 android:id="@+id/cancelButton" 72 android:layout_width="match_parent" 73 android:layout_height="match_parent" 74 android:layout_weight="1" 75 android:background="@drawable/botton_border" 76 android:text="キャンセル" 77 android:textSize="25sp" 78 app:layout_constraintStart_toStartOf="parent" /> 79 80 <Button 81 android:id="@+id/saveButton" 82 android:layout_width="match_parent" 83 android:layout_height="match_parent" 84 android:layout_weight="1" 85 android:background="@drawable/botton_border" 86 android:text="保存" 87 android:textSize="25sp" /> 88 </LinearLayout> 89 90</androidx.constraintlayout.widget.ConstraintLayout>

画面デザイン
イメージ説明

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

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

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

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

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

jimbe

2020/04/04 13:26

kotlin としてはどうでもよいことですが, 「Morinig」とは? 「Morning」のことでしょうか.
jimbe

2020/04/04 13:32

マークダウンで ``` の右に書くのはファイル名では無く言語名("kotlin","xml"等)としてください. ファイル名は ```の行の直前にでも通常の文としてお書きください.
kbayashi

2020/04/04 23:51

ご指摘ありがとうございます。Morinigはタイピングミスをしていました。気づきませんでした。また、マークダウンの方も本来の書き方に修正させていただきました。
jimbe

2020/04/05 03:28

修正ありがとうございます
guest

回答1

0

ベストアンサー

ダイアログに ReminderMorinigImage が見当たりません.

#追記
ダイアログのレイアウト設定は onCreateDialog() 内で行われていますので, show() の前にはビューはまだ生成されていません.
形としては, ダイアログに(newInstance 経由で setArguments を用いて「どちらのボタンを表示するのか」だけを渡し, onCreateDialog 内でそのパラメータから両ボタンの GONE/VISIBLE を設定しては如何でしょうか.

...再度見ていたのですが, onCreateDialog 内で val now = Calendar.getInstance() して処理している個所がありますので, そこに //時刻が夜の6時より前だったら ~ の if 文部分を移してしまえばよいのではないでしょうか.
そうすれば TaskAddActivity の onCreate ではボタンが押されたらダイアログを生成して表示するだけになると思います.

投稿2020/04/04 13:30

編集2020/04/05 05:09
jimbe

総合スコア13209

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

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

jimbe

2020/04/05 05:35

少々気になったのは, このようにコードの知らないところで状況が変わるもの(時刻)によってインターフェースが変わる場合, その変わる前に表示した状態が変わった後にも問題無いか...ということです. 具体的には, 18時前にダイアログを表示して reminderMorningButton が VISIBLE, reminderNightButton が GONE となった状態で18時を過ぎた場合, 18時以降であれば押せないはずの reminderMorningButton を押せてしまうことになりますが, 大丈夫でしょうか. わざわざ消しているということは, その時間帯には押せないことを前提にコードが書かれている可能性があります.
kbayashi

2020/04/05 11:19

回答ありがとうございます。 reminderNightButtonを使用して実装したい処理は、それが押された場合は今日の20時に、アプリから通知を行うという処理で、仮に20時より後に押されてしまっても通知が作動しないだけなので、この問題は許容しています。
kbayashi

2020/04/05 11:27

onCreateDialog内でボタンの非表示処理を書いたところ正常に動作しました。ありがとうございます。
jimbe

2020/04/05 14:25

> 今日の20時に、アプリから通知を行うという処理 なるほど, プリセットボタンなんですね. 便利そうです.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問