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

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

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

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

Android Studio

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

Q&A

解決済

1回答

447閲覧

【AndroidStudio (Java)】 DatePickerDialogを使用してカレンダーから年月日を取得する

liptoon

総合スコア7

Java

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

Android Studio

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

0グッド

0クリップ

投稿2024/02/22 00:58

実現したいこと

入力ボタンを押すことでカレンダーを表示
→クリックした年月日を取得
→入力ボタンがあるページにあるテキストボックスへ表示させる

発生している問題・分からないこと

入力ボタンを押すとアプリが停止する。

エラーメッセージ

error

1 FATAL EXCEPTION: main 2Process: com.websarva.wings.android.error, PID: 26049 3java.lang.ClassCastException: com.websarva.wings.android.error.MainActivity cannot be cast to android.app.DatePickerDialog$OnDateSetListener 4 at com.websarva.wings.android.error.SampleFragment$DatePickerFragment.onCreateDialog(SampleFragment.java:51) 5 at androidx.fragment.app.DialogFragment.prepareDialog(DialogFragment.java:644) 6 at androidx.fragment.app.DialogFragment.onGetLayoutInflater(DialogFragment.java:558) 7 at androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1654) 8 at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:493) 9 at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282) 10 at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189) 11 at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100) 12 at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002) 13 at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:524) 14 at android.os.Handler.handleCallback(Handler.java:942) 15 at android.os.Handler.dispatchMessage(Handler.java:99) 16 at android.os.Looper.loopOnce(Looper.java:201) 17 at android.os.Looper.loop(Looper.java:288) 18 at android.app.ActivityThread.main(ActivityThread.java:7872) 19 at java.lang.reflect.Method.invoke(Native Method) 20 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 21 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) 22

該当のソースコード

Java

1public class MainActivity extends AppCompatActivity { 2 @Override 3 protected void onCreate(Bundle savedInstanceState) { 4 super.onCreate(savedInstanceState); 5 setContentView(R.layout.activity_main); 6 } 7}

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.fragment.app.FragmentContainerView 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:id="@+id/fragmentMainContainer" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 android:name="com.websarva.wings.android.error.SampleFragment" 9 tools:layout="@layout/fragment_sample" />

Java

1public class SampleFragment extends Fragment implements DatePickerDialog.OnDateSetListener{ 2 3 public SampleFragment() { 4 super(R.layout.fragment_sample); 5 } 6 7 @Override 8 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 9 super.onViewCreated(view, savedInstanceState); 10 11 //期間入力ボタンにリスナ設定 12 Button btPeriod=view.findViewById(R.id.btPeriod); 13 btPeriod.setOnClickListener(new BtPeriodClickListener()); 14 } 15 16 17 public static class DatePickerFragment extends DialogFragment{ 18 @Override 19 public Dialog onCreateDialog(Bundle savedInstanceState) { 20 21 //このフラグメントが所属するアクティビティオブジェクトを取得 22 Activity parentActivity=getActivity(); 23 // Use the current date as the default date in the picker. 24 final Calendar cl = Calendar.getInstance(); 25 int year = cl.get(Calendar.YEAR); 26 int month = cl.get(Calendar.MONTH); 27 int day = cl.get(Calendar.DAY_OF_MONTH); 28 29 // Create a new instance of DatePickerDialog and return it. 30 return new DatePickerDialog(parentActivity, (DatePickerDialog.OnDateSetListener)getActivity(), year, month, day); 31 } 32 } 33 34 @Override 35 public void onDateSet(DatePicker view, int year, int month, int day) { 36 TextView inputDate=view.findViewById(R.id.tvPeriodDisplay); 37 String outputDate=String.format("%d/%d/%d", year, month+1, day); 38 inputDate.setText(outputDate); 39 } 40 41 42 private class BtPeriodClickListener implements View.OnClickListener { 43 @Override 44 public void onClick(View view) { 45 DatePickerFragment dpFragment= new DatePickerFragment(); 46 dpFragment.show(getActivity().getSupportFragmentManager(), "datePicker"); 47 } 48 } 49}

xml

1<?xml version="1.0" encoding="utf-8"?> 2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 xmlns:app="http://schemas.android.com/apk/res-auto" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 android:baselineAligned="true" 8 android:orientation="vertical"> 9 10 <LinearLayout 11 android:layout_width="match_parent" 12 android:layout_height="wrap_content" 13 android:layout_marginStart="32dp" 14 android:layout_marginEnd="32dp" 15 android:orientation="horizontal"> 16 17 <TextView 18 android:id="@+id/tvPeriod" 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:text="期間" 22 android:textSize="20sp" /> 23 24 <Button 25 android:id="@+id/btPeriod" 26 android:layout_width="wrap_content" 27 android:layout_height="wrap_content" 28 android:layout_marginStart="8dp" 29 android:layout_marginEnd="8dp" 30 android:backgroundTint="@android:color/darker_gray" 31 android:text="入力" 32 android:textColor="@color/black" /> 33 34 <TextView 35 android:id="@+id/tvPeriodDisplay" 36 android:layout_width="wrap_content" 37 android:layout_height="wrap_content" 38 android:ems="10" 39 android:background="@android:color/darker_gray" 40 android:textSize="20sp" 41 tools:ignore="SpeakableTextPresentCheck" /> 42 43 </LinearLayout> 44</LinearLayout> 45

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

お世話になっております。
Javaを学び始め、初めてアプリ作成に取り組んでいます。
今回の機能実装にあたり、以下サイトを参考にしました。
参考①https://qiita.com/Pon2929/items/4024835c89406b0a6237
https://developer.android.com/develop/ui/views/components/pickers?hl=ja

com.websarva.wings.android.error.MainActivity cannot be cast to android.app.DatePickerDialog$OnDateSetListener

このエラーメッセージをみてもMainActivityがなぜ関係しているのか理解できず、何を試せばよいのかわからない状況です。
ヒントとなるような小さなこと、なんでも構いませんのでアドバイスいただけると大変たすかります。
どうぞよろしくお願いいたします。

補足

AndroidStudio giraffe

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

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

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

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

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

guest

回答1

0

ベストアンサー

ClassCastException: com.websarva.wings.android.error.MainActivity cannot be cast to android.app.DatePickerDialog$OnDateSetListener at com.websarva.wings.android.error.SampleFragment$DatePickerFragment.onCreateDialog(SampleFragment.java:51)

は、 import 等が省略されているため行番号が一致しませんが

java

1 // Create a new instance of DatePickerDialog and return it. 2 return new DatePickerDialog(parentActivity, (DatePickerDialog.OnDateSetListener)getActivity(), year, month, day);

の個所で「 (getActivity で得られる )MainActivity が DatePickerDialog.OnDateSetListener では無い ( からキャスト出来ない ) 」と言われています。

このエラーメッセージをみてもMainActivityがなぜ関係しているのか

SampleFragment 内に getActivity が幾つもあり、 MainActivity を使っています。例外の個所はそのうちの 1 つです。
使っているのを分からなかったということは、元のコードがどこで何をする為にどう書かれていたのかを読み切れていなかったということでしょう。

また、リンク先の記事に

DatePickerDialogFragmentクラスにOnDateSetメソッドを書いた場合、どのような記述をすれば選択した日付をtestDatePickerActivityに表示できるのかわからなかった。onDateSetメソッドをtestDatePickerActivityで継承したらなんとかできたのでよかったねというお話でした。

とありますが、この構造はフラグメントの親が何なのかが決まっていることを前提にしており、それはフラグメントの独立性として良いものではありません。
フラグメントの結果は FragmentResult (や ViewModel) を用いて間接的に他に伝えるようにするべきと思います。


とりあえず FragmentResult とかは置いておいて SimpleFragment 内で完結するならこんな感じでしょうか。

  • DatePickerDialog コンストラクタの第 2 引数として指定する OnDateSetListener は、 MainActivity では無く SampleFragment を指すようにする。(DatePickerFragment 内で getParentFragment で得られる)
  • DatePickerDialog ダイアログを管理(表示)するのは、アクティビティのフラグメントマネージャで無く直接の親である SampleFragment のフラグメントマネージャとする。(SampleFragment 内で getChildFragmentManager で得られる)
  • コンテキストは requireContext で得られる。
  • OnDateSetListener の onDateSet メソッドの第 1 引数の view はカレンダーなので view.findViewById(R.id.tvPeriodDisplay) しても SimpleFragment のレイアウト上のものは取れない。 SampleFrament のコンストラクタで View を得ておいて使うのが簡単。

java

1import android.app.*; 2import android.os.Bundle; 3import android.view.View; 4import android.widget.*; 5 6import androidx.annotation.*; 7import androidx.fragment.app.DialogFragment; 8import androidx.fragment.app.Fragment; 9 10import java.util.Calendar; 11 12public class SampleFragment extends Fragment implements DatePickerDialog.OnDateSetListener { 13 private TextView inputDate; 14 15 public SampleFragment() { 16 super(R.layout.fragment_sample); 17 } 18 19 @Override 20 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 21 super.onViewCreated(view, savedInstanceState); 22 23 inputDate = view.findViewById(R.id.tvPeriodDisplay); 24 25 Button btPeriod = view.findViewById(R.id.btPeriod); 26 btPeriod.setOnClickListener(new BtPeriodClickListener()); 27 } 28 29 public static class DatePickerFragment extends DialogFragment { 30 @Override 31 public Dialog onCreateDialog(Bundle savedInstanceState) { 32 final Calendar cl = Calendar.getInstance(); 33 int year = cl.get(Calendar.YEAR); 34 int month = cl.get(Calendar.MONTH); 35 int day = cl.get(Calendar.DAY_OF_MONTH); 36 return new DatePickerDialog(requireContext(), (DatePickerDialog.OnDateSetListener)getParentFragment(), year, month, day); 37 } 38 } 39 40 @Override 41 public void onDateSet(DatePicker view, int year, int month, int day) { 42 String outputDate = String.format("%d/%d/%d", year, month+1, day); 43 inputDate.setText(outputDate); 44 } 45 46 private class BtPeriodClickListener implements View.OnClickListener { 47 @Override 48 public void onClick(View view) { 49 DatePickerFragment dpFragment= new DatePickerFragment(); 50 dpFragment.show(getChildFragmentManager(), null); 51 } 52 } 53}

投稿2024/02/22 04:33

編集2024/02/23 09:45
jimbe

総合スコア12775

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

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

liptoon

2024/02/22 22:21

回答ありがとうございます。疑問に思ってずっと悩んでいたものが一気に解決しました! > import 等が省略されているため行番号が一致しません すみません、確かにそうですよね・・・全然考えられていませんでした。行数出しているときは省略しないように気を付けます とても丁寧に説明してくださりたいへん助かりました。 フラグメントの独立性についても言及してくださり勉強になりました。 この度はほんとうにありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問