Android Fragment中DatePickerDialog点击OK闪退问题求助
解决Fragment中DatePickerDialog点击OK崩溃的问题
嘿,我仔细看了你的代码和崩溃日志,问题出在两个关键细节上,都是引发NullPointerException的根源,咱们一步步来搞定:
1. 局部变量覆盖成员变量,导致TextView对象为空
在onCreateView方法里,你重新声明了局部的hariDisplay、tanggalDisplay、bulanDisplay变量,比如:
TextView hariDisplay = root.findViewById(R.id.text_hari_riwayat);
这会让类的成员变量始终处于null状态!当你在onDateSet回调里调用bulanDisplay.setText(bulan)时,自然就触发了空指针异常。
解决方法:去掉局部变量的类型声明,直接给成员变量赋值:
// 去掉前面的TextView,直接使用类的成员变量 hariDisplay = root.findViewById(R.id.text_hari_riwayat); tanggalDisplay = root.findViewById(R.id.text_tanggal_riwayat); bulanDisplay = root.findViewById(R.id.text_bulan_riwayat); // 这里还要注意id匹配!
另外要注意:你的成员变量bulanDisplay原本绑定的是R.id.text_riwayat,但布局里的月份TextView id是text_bulan_riwayat,这也会导致findViewById找不到控件返回null,必须修正这个id匹配问题!
2. DatePickerDialog的Listener初始化顺序错误
你现在的代码是先创建DatePickerDialog并传入还未初始化的dateSetListener(此时它是null),之后才初始化listener:
datePickerDialog = new DatePickerDialog(requireContext(), dateSetListener, year, month, day); // ... dateSetListener = new DatePickerDialog.OnDateSetListener(){...};
这会导致DatePickerDialog持有的是null的listener,点击OK时无法正确触发回调,甚至引发异常。
解决方法:先初始化dateSetListener,再创建DatePickerDialog:
private void showDateDialog(){ Calendar calendar = Calendar.getInstance(); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int day = calendar.get(Calendar.DAY_OF_MONTH); // 先初始化监听回调 dateSetListener = new DatePickerDialog.OnDateSetListener(){ @Override public void onDateSet(DatePicker datePicker, int year, int month, int day) { month = month + 1; bulan = month + " " + year; tanggal = String.valueOf(day); // 现在TextView都已正确初始化,可以安全调用setText bulanDisplay.setText(bulan); tanggalDisplay.setText(tanggal); } }; // 再创建对话框并传入已初始化的listener datePickerDialog = new DatePickerDialog(requireContext(), dateSetListener, year, month, day); datePickerDialog.show(); }
修改后的完整NotificationsFragment关键代码
public class NotificationsFragment extends Fragment { private NotificationsViewModel notificationsViewModel; private DatePickerDialog datePickerDialog; private Button lihatBtn; private TextView tanggalDisplay, hariDisplay, bulanDisplay; private CardView cardView; private SimpleDateFormat simpleDateFormat; private String hari, tanggal, bulan; private DatePickerDialog.OnDateSetListener dateSetListener; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { notificationsViewModel = new ViewModelProvider(this).get(NotificationsViewModel.class); View root = inflater.inflate(R.layout.fragment_notifications, container, false); simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy", Locale.US); // 修正:直接给成员变量赋值,不声明局部变量 hariDisplay = root.findViewById(R.id.text_hari_riwayat); tanggalDisplay = root.findViewById(R.id.text_tanggal_riwayat); bulanDisplay = root.findViewById(R.id.text_bulan_riwayat); // 修正id匹配 cardView = root.findViewById(R.id.card_date); lihatBtn = root.findViewById(R.id.lihat); cardView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showDateDialog(); } }); return root; } private void showDateDialog(){ Calendar calendar = Calendar.getInstance(); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int day = calendar.get(Calendar.DAY_OF_MONTH); // 先初始化监听回调 dateSetListener = new DatePickerDialog.OnDateSetListener(){ @Override public void onDateSet(DatePicker datePicker, int year, int month, int day) { month = month + 1; bulan = month + " " + year; tanggal = String.valueOf(day); bulanDisplay.setText(bulan); tanggalDisplay.setText(tanggal); } }; // 再创建对话框 datePickerDialog = new DatePickerDialog(requireContext(), dateSetListener, year, month, day); datePickerDialog.show(); } }
做完这两处修改后,你的DatePickerDialog点击OK按钮就不会再崩溃了,而且能正确更新TextView的内容。
内容的提问来源于stack exchange,提问作者vvvv
相关产品推荐
相关产品推荐

