java - MainActivity 无法强制转换为 android.app.TimePickerDialog$OnTimeSetListener 无法解决
问题描述
我不知道为什么我要改变一个活动来分段它没有按预期工作。
020-06-22 14:18:38.973 13510-13510/com.vikaskonaparthi.time E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.vikaskonaparthi.time, PID: 13510
java.lang.ClassCastException: com.vikaskonaparthi.time.MainActivity cannot be cast to android.app.TimePickerDialog$OnTimeSetListener
at com.vikaskonaparthi.time.dialogs.TimePickerDialogFragment.onAttach(TimePickerDialogFragment.java:29)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1247)
at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2431)
at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2210)
at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2166)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2067)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:742)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7397)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
这是 Timepicker 对话框片段
public class TimePickerDialogFragment extends DialogFragment {
private int hour;
private int minute;
private TimePickerDialog.OnTimeSetListener listener;
public static final String FRAGMENT_TAG = "time_picker";
public static final String BUNDLE_KEY_ALARM_HOUR = "alarm_hour";
public static final String BUNDLE_KEY_ALARM_MINUTE = "alarm_minute";
@Override
public void onAttach(Context context) {
super.onAttach(context);
listener = (TimePickerDialog.OnTimeSetListener) context;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle bundle = getArguments();
hour = bundle.getInt(BUNDLE_KEY_ALARM_HOUR);
minute = bundle.getInt(BUNDLE_KEY_ALARM_MINUTE);
final AlarmTimePickerDialog timePickerDialog = new AlarmTimePickerDialog(getActivity(), listener, hour, minute, true);
LayoutInflater inflater = LayoutInflater.from(getActivity());
View customTitleView = inflater.inflate(R.layout.partial_timepicker_dialog_title, null);
timePickerDialog.setCustomTitle(customTitleView);
timePickerDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
timePickerDialog.showTimeLeft(hour, minute);
}
});
return timePickerDialog;
}
}
这是警报对话框
public class AlarmTimePickerDialog extends TimePickerDialog {
public AlarmTimePickerDialog(Context context, OnTimeSetListener listener, int hourOfDay, int minute,
boolean is24HourView) {
super(context, listener, hourOfDay, minute, is24HourView);
}
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
super.onTimeChanged(view, hourOfDay, minute);
showTimeLeft(hourOfDay, minute);
}
@Override
public void setCustomTitle(View customTitleView) {
if (getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { //title is displayed in portrait orientation only
super.setCustomTitle(customTitleView);
}
}
public void showTimeLeft(int hour, int minute) {
if (getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
TextView textView = (TextView) this.findViewById(R.id.textview_timepickerdialog_timeleft);
AlarmTime time = new AlarmTime(hour, minute);
textView.setText(getContext().getString(R.string.all_time_left, time.getHoursLeft(), time.getMinutesLeft()));
}
}
}
我见过很多这样的东西并尝试过,但没有任何效果。实际上,这段代码在活动中运行良好,但是当我将活动更改为碎片时,错误正在抛出。
先感谢您。
public class Fragment1 extends Fragment implements
IntervalDialogFragment.IntervalDialogListener,
NumberOfAlarmsDialogFragment.NumberOfAlarmsDialogListener,
TimePickerDialog.OnTimeSetListener{
SwitchCompat onOffSwitch;
ListView alarmsListView;
TextView intervalBetweenAlarmsTextView;
TextView numberOfAlarmsTextView;
TextView firstAlarmTextView;
TextView timeLeftTextView;
LinearLayout firstAlarmLayout;
LinearLayout intervalLayout;
LinearLayout numberOfAlarmsLayout;
AlarmsListHelper alarmsListHelper;
SharedPreferencesHelper sharPrefHelper;
TimerManager timerManager;
AlarmParams alarmParams;
BroadcastReceiver timeLeftReceiver;
private final String LOG_TAG = Fragment1.class.getSimpleName();
final int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 45;
final float DISPLAYED_NUMBERS_SIZE_RELATIVE_TO_TEXT_PROPORTION = 2f; // number of alarms, first alarm, interval values text size is larger than text around them
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment1,container,false);
alarmsListView = (ListView) root.findViewById(R.id.listview_main_alarmslist);
onOffSwitch = (SwitchCompat) root.findViewById(R.id.switch_main);
intervalBetweenAlarmsTextView = (TextView) root.findViewById(R.id.textview_main_interval);
numberOfAlarmsTextView = (TextView) root.findViewById(R.id.textview_main_numberofalarms);
firstAlarmLayout = (LinearLayout) root.findViewById(R.id.layout_main_firstalarm);
firstAlarmTextView = (TextView) root.findViewById(R.id.textview_main_firstalarm_time);
timeLeftTextView = (TextView) root.findViewById(R.id.textview_main_timeleft);
intervalLayout = (LinearLayout) root.findViewById(R.id.layout_main_interval);
numberOfAlarmsLayout = (LinearLayout) root.findViewById(R.id.layout_main_numberofalarms);
sharPrefHelper = new SharedPreferencesHelper(getActivity());
sharPrefHelper.printAll();
alarmParams = sharPrefHelper.getParams();
timerManager = new TimerManager(getActivity());
alarmsListHelper = new AlarmsListHelper(getActivity(), alarmsListView);
showFirstAlarmTime(alarmParams.firstAlarmTime.toString());
showTimeLeft(alarmParams);
showInterval(sharPrefHelper.getIntervalStr());
showNumberOfAlarms(sharPrefHelper.getNumberOfAlarmsStr());
onOffSwitch.setChecked(sharPrefHelper.isAlarmTurnedOn());
alarmsListHelper.showList(alarmParams);
onOffSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
alarmParams.turnedOn = isChecked;
if (isChecked) {
checkNotificationPolicy();
checkOverlayPermission();
timerManager.startSingleAlarmTimer(alarmParams.firstAlarmTime.toMillis());
showToast(getString(R.string.main_alarm_turned_on_toast));
sharPrefHelper.setNumberOfAlreadyRangAlarms(0);
} else {
timerManager.cancelTimer();
showToast(getString(R.string.main_alarm_turned_off_toast));
}
alarmsListHelper.showList(alarmParams);
showTimeLeft(alarmParams);
sharPrefHelper.setAlarmState(isChecked);
}
});
intervalLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
IntervalDialogFragment dialog = new IntervalDialogFragment();
Bundle intervalBundle = new Bundle();
intervalBundle.putString(IntervalDialogFragment.BUNDLE_KEY_INTERVAL, sharPrefHelper.getIntervalStr());
dialog.setArguments(intervalBundle);
dialog.show(getActivity().getFragmentManager(), IntervalDialogFragment.FRAGMENT_TAG);
}
});
numberOfAlarmsLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
NumberOfAlarmsDialogFragment dialog = new NumberOfAlarmsDialogFragment();
Bundle numberOfAlarmsBundle = new Bundle();
numberOfAlarmsBundle.putString(NumberOfAlarmsDialogFragment.BUNDLE_KEY_NUMBER_OF_ALARMS, sharPrefHelper.getNumberOfAlarmsStr());
dialog.setArguments(numberOfAlarmsBundle);
dialog.show(getActivity().getFragmentManager(), NumberOfAlarmsDialogFragment.FRAGMENT_TAG);
}
});
firstAlarmLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle timePickerBundle = new Bundle();
timePickerBundle.putInt(TimePickerDialogFragment.BUNDLE_KEY_ALARM_HOUR, sharPrefHelper.getHour());
timePickerBundle.putInt(TimePickerDialogFragment.BUNDLE_KEY_ALARM_MINUTE, sharPrefHelper.getMinute());
TimePickerDialogFragment timePicker = new TimePickerDialogFragment();
timePicker.setArguments(timePickerBundle);
timePicker.show(getActivity().getFragmentManager(), TimePickerDialogFragment.FRAGMENT_TAG);
}
});
return root;
}
@Override
public void onResume() {
super.onResume();
showTimeLeft(alarmParams);
timeLeftReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context ctx, Intent intent) {
if (intent.getAction().compareTo(Intent.ACTION_TIME_TICK) == 0) { //i.e. every minute
showTimeLeft(alarmParams);
}
}
};
getActivity().registerReceiver(timeLeftReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
}
@Override
public void onPause() {
super.onPause();
if (timeLeftReceiver != null) {
getActivity().unregisterReceiver(timeLeftReceiver);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_settings: {
Intent intent = new Intent(getActivity(), PrefActivity.class);
startActivity(intent);
break;
}
}
return super.onOptionsItemSelected(item);
}
@Override
public void onIntervalChanged(String intervalStr) {
showInterval(intervalStr);
alarmParams.interval = Integer.parseInt(intervalStr);
alarmsListHelper.showList(alarmParams);
resetTimerIfTurnedOn();
sharPrefHelper.setInterval(intervalStr);
}
@Override
public void onNumberOfAlarmsChanged(String numberOfAlarmsStr) {
showNumberOfAlarms(numberOfAlarmsStr);
alarmParams.numberOfAlarms = Integer.parseInt(numberOfAlarmsStr);
alarmsListHelper.showList(alarmParams);
resetTimerIfTurnedOn();
sharPrefHelper.setNumberOfAlarms(numberOfAlarmsStr);
}
@Override
public void onTimeSet(TimePicker view, int hour, int minute) {
AlarmTime alarmTime = new AlarmTime(hour, minute);
alarmParams.firstAlarmTime = alarmTime;
showFirstAlarmTime(alarmTime.toString());
alarmsListHelper.showList(alarmParams);
showTimeLeft(alarmParams);
sharPrefHelper.setNumberOfAlreadyRangAlarms(0);
resetTimerIfTurnedOn();
sharPrefHelper.setTime(alarmTime);
}
private void showToast(String message) {
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
}
private void resetTimerIfTurnedOn() {
if (onOffSwitch.isChecked()) {
timerManager.resetSingleAlarmTimer(alarmParams.firstAlarmTime.toMillis());
showToast(getString(R.string.main_alarm_reset_toast));
}
}
private void showInterval(String interval) {
String wholeTitle = getString(R.string.main_interval, interval);
SpannableString wholeTitleSpan = new SpannableString(wholeTitle);
wholeTitleSpan.setSpan(new RelativeSizeSpan(DISPLAYED_NUMBERS_SIZE_RELATIVE_TO_TEXT_PROPORTION), wholeTitle.indexOf(interval), interval.length() + 1, 0);
intervalBetweenAlarmsTextView.setText(wholeTitleSpan);
}
private void showNumberOfAlarms(String numberOfAlarms) {
int numberOfAlarmsInt = Integer.parseInt(numberOfAlarms);
String wholeTitle = this.getResources().getQuantityString(R.plurals.main_number_of_alarms, numberOfAlarmsInt, numberOfAlarmsInt);
SpannableString wholeTitleSpan = new SpannableString(wholeTitle);
wholeTitleSpan.setSpan(new RelativeSizeSpan(DISPLAYED_NUMBERS_SIZE_RELATIVE_TO_TEXT_PROPORTION),
wholeTitle.indexOf(numberOfAlarms),
numberOfAlarms.length() + 1, 0);
numberOfAlarmsTextView.setText(wholeTitleSpan);
}
private void showFirstAlarmTime(String firstAlarmTime) {
String wholeTitle = getString(R.string.main_firstalarm_time, firstAlarmTime);
SpannableString wholeTitleSpan = new SpannableString(wholeTitle);
wholeTitleSpan.setSpan(new RelativeSizeSpan(DISPLAYED_NUMBERS_SIZE_RELATIVE_TO_TEXT_PROPORTION),
wholeTitle.indexOf(firstAlarmTime) - 1,
wholeTitle.indexOf(firstAlarmTime) + firstAlarmTime.length(), 0);
firstAlarmTextView.setText(wholeTitleSpan);
}
private void showTimeLeft(AlarmParams alarmParams) {
AlarmTime alarmTime = alarmParams.firstAlarmTime;
timeLeftTextView.setText(getString(R.string.all_time_left, alarmTime.getHoursLeft(), alarmTime.getMinutesLeft()));
if (alarmParams.turnedOn) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
timeLeftTextView.setTextColor(getActivity().getColor(R.color.primary));
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
timeLeftTextView.setTextColor(getActivity().getColor(R.color.main_disabled_textcolor));
}
}
Log.d(LOG_TAG, "Time left: "+alarmTime.getHoursLeft() + ":" + alarmTime.getMinutesLeft());
}
private void checkNotificationPolicy() {
NotificationManager notificationManager =
(NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& !notificationManager.isNotificationPolicyAccessGranted()) {
Intent intent = new Intent(
android.provider.Settings
.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivity(intent);
}
}
/**
* needed for Android Q: on some devices activity doesn't show from fullScreenNotification without
* permission SYSTEM_ALERT_WINDOW
*/
private void checkOverlayPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.P) && (!Settings.canDrawOverlays(getActivity()))) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getActivity().getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}
}
}
}
解决方案
尝试为您的片段实现 TimePickerDialog.OnTimeSetListener:
public class TimePickerDialogFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener
////
@Override
public void onAttach(Context context) {
super.onAttach(context);
listener = this;
}
@Override
public void onTimeSet(TimePicker timePicker, int i, int i1) {
// get selected time
}
推荐阅读
- android - React Native 错误任务:app:checkDebugAarMetadata | 任务“:app:checkDebugAarMetadata”执行失败
- sql - 为什么在选择查询中使用 PARALLEL 是什么 tgge 目的?
- karate - 我在连接两个 JSON 值以在我的空手道场景中执行 !contains 时遇到问题,如果我单独为每个字段运行匹配,它就可以工作
- java - 安卓链接电话号码
- angular - 单击 div 后,如何以角度传递我的 div id
- python - pyinstaller ModuleNotFoundError:没有名为“桨”的模块
- python - Odoo 13 CE 无法创建或编辑用户?
- animation - 为什么在 THREE.js 中,Object3D.translateX 中的算术表达式未按预期进行评估,或者 Vector.copy 在动画循环中无法正常工作?
- java - Gradle 复合构建无法解决传递依赖
- c# - 有没有动态的方法将 100 分成不同的值?