You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:47:06