Android ClassCastException при реализации метода onTimeSet интерфейса TimePickerDialog.OnTimeSetListener в другом фрагменте - PullRequest
0 голосов
/ 25 апреля 2020

Я пытаюсь реализовать TimePickerDialog.OnTimeSetListener во фрагменте, но при этом сталкиваюсь с ClassCastException.

Вот код TimePickerFragment класса:

public class TimePickerFragment extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        final Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);

        return new TimePickerDialog(
                getActivity(),
                (TimePickerDialog.OnTimeSetListener) getActivity(),
//                this,
                hour,
                minute,
                DateFormat.is24HourFormat(getActivity())
        );
    }
}

Мне нужно использовать значения часов и минут, выбранные пользователем в другом фрагменте с именем SetAlarmFragment. И поэтому я реализовал TimePickerDialog.OnTimeSetListener в этом фрагменте. Вот код:

public class SetAlarmFragment extends Fragment implements TimePickerDialog.OnTimeSetListener {

    private TextView timeText;
    private Button timePickerButton;
    private Button confirmationButton;

    private int selectedHour;
    private int selectedMinute;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_set_alarm, container, false);

        initializeUiComponents(view);
        setClickEvents();

        final Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);

        updateTimeText(hour, minute);

        return view;
    }

    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        updateTimeText(hourOfDay, minute);
    }

    private void setClickEvents() {
        // to edit time
        timePickerButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DialogFragment timePickerFragment = new TimePickerFragment();
                timePickerFragment.show(getFragmentManager(), "timePicker");
            }
        });

        // on confirmation button pressed
        confirmationButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar cal = Calendar.getInstance();
                AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
                Intent intent = new Intent(getActivity(), AlarmReceiver.class);
                PendingIntent alarmIntent = PendingIntent.getBroadcast(getActivity(), 0, intent, 0);
                if (Build.VERSION.SDK_INT >= 19) {
                    alarmManager.setExact(
                            AlarmManager.RTC_WAKEUP,
                            cal.getTimeInMillis(),
                            alarmIntent
                    );
                } else {
                    alarmManager.set(
                            AlarmManager.RTC_WAKEUP,
                            cal.getTimeInMillis(),
                            alarmIntent
                    );
                }
            }
        });
    }

    private void initializeUiComponents(View view) {
        timeText = view.findViewById(R.id.time_text);
        timePickerButton = view.findViewById(R.id.set_time_button);
        confirmationButton = view.findViewById(R.id.confirm_button);
    }


    private void updateTimeText(int hour, int minute) {
        selectedHour = hour;
        selectedMinute = minute;
        timeText.setText(
                String.format("%d:%d", selectedHour, selectedMinute)
        );
    }
}

Теперь я предполагаю, что причина этой проблемы в том, что я внедряю метод onTimeSet() во фрагмент, а не в действие. Но мне нужно, чтобы значение часа и минуты было выбрано из TimePicker в SetAlarmFragment. Использование действия вместо фрагмента может решить эту проблему, но я хочу избежать этого, насколько смогу. Как я могу решить эту проблему?

Вот сообщение об ошибке:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.apphousebd.digitalmcq.beta, PID: 4467
    java.lang.ClassCastException: com.apphousebd.digitalmcq.mainUi.MainActivity cannot be cast to android.app.TimePickerDialog$OnTimeSetListener
        at com.apphousebd.digitalmcq.fragments.TimePickerFragment.onCreateDialog(TimePickerFragment.java:26)
        at androidx.fragment.app.DialogFragment.onGetLayoutInflater(DialogFragment.java:380)
        at androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1412)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
        at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:201)
        at android.app.ActivityThread.main(ActivityThread.java:6810)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
E/UncaughtException: java.lang.ClassCastException: com.apphousebd.digitalmcq.mainUi.MainActivity cannot be cast to android.app.TimePickerDialog$OnTimeSetListener
        at com.apphousebd.digitalmcq.fragments.TimePickerFragment.onCreateDialog(TimePickerFragment.java:26)
        at androidx.fragment.app.DialogFragment.onGetLayoutInflater(DialogFragment.java:380)
        at androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1412)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
        at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:201)
        at android.app.ActivityThread.main(ActivityThread.java:6810)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

1 Ответ

1 голос
/ 25 апреля 2020
return new TimePickerDialog(
                getActivity(),
                (TimePickerDialog.OnTimeSetListener) getActivity(),
//                this,
                hour,
                minute,
                DateFormat.is24HourFormat(getActivity())
        );

Здесь вы вызываете активность. В основном здесь:

(TimePickerDialog.OnTimeSetListener) getActivity ()

Но TimePickerDialog.OnTimeSetListener реализуется фрагментом, а не действием. Вот почему ошибка говорит о том, что MainActivity нельзя преобразовать в android .app.TimePickerDialog $ OnTimeSetListener . Потому что MainActivity не реализует его. Но при вызове getActivity () вызывается MainActivity . Измените TimePickerFragment возвращаемое значение класса.

...