当屏幕方向改变时,打开日期对话框时强制关闭问题

5

我有一个Activity,我想要的是:

当某个包含TextView的布局被点击时,打开日期选择器,并将所选值设置为txtvalue。

我想使用以下代码通过DialogFragment访问DatePicker:

package com.app.ourforms.date;

import java.util.Calendar;

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.os.Bundle;
import android.util.Log;
import android.widget.DatePicker;
import android.widget.TextView;

public class DatePickerFragment extends DialogFragment implements
        DatePickerDialog.OnDateSetListener {

    TextView txt;

    public DatePickerFragment() {
    }

    public DatePickerFragment(TextView txt) {
        this.txt = txt;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceSateate) {

        Log.i("TAG", "Inside onCreateDialog");
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        return new DatePickerDialog(getActivity(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        Log.i("TAG", "Inside onDateSet");
        txt.setText(day + "/" + (month + 1) + "/" + year);
        // Do something with the date chosen
    }
}

当设备不改变其方向时,上述代码可以正常工作。但是当日期选择器显示并且方向发生变化时,我会遇到强制关闭的问题,如下所示。
01-04 07:34:14.580: E/AndroidRuntime(2375): FATAL EXCEPTION: main
01-04 07:34:14.580: E/AndroidRuntime(2375): java.lang.NullPointerException
01-04 07:34:14.580: E/AndroidRuntime(2375):     at com.app.ourforms.date.DatePickerFragment.onDateSet(DatePickerFragment.java:39)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at android.app.DatePickerDialog.tryNotifyDateSet(DatePickerDialog.java:148)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at android.app.DatePickerDialog.onClick(DatePickerDialog.java:116)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at android.os.Looper.loop(Looper.java:137)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at android.app.ActivityThread.main(ActivityThread.java:5039)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at java.lang.reflect.Method.invokeNative(Native Method)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at java.lang.reflect.Method.invoke(Method.java:511)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-04 07:34:14.580: E/AndroidRuntime(2375):     at dalvik.system.NativeStart.main(Native Method)

这是我的调用DatePickerFragment的方法:

public void showDatePickerDialog(View v) {
        Log.i("TAG", "Inside showDatePickerDialog");
        DialogFragment newFragment = new DatePickerFragment((TextView)v);
        newFragment.show(getFragmentManager(), "datePicker");
    }

请帮助我摆脱这个问题。谢谢您的帮助。

2个回答

2

我不确定这个解决方案是否适用于您,但您可以尝试一下。

您面临的问题是因为每次方向改变时,您的Activity都会重新加载。您可以调用OnConfigurationchanged()方法,并在Menifest文件中将Configuchanges设置为orientation|screensize

通过这样做,当方向改变时,您的Activity将不会重新加载,您将不再遇到当前面临的问题。

希望对您有所帮助。


1

您的TextView引用为空。NPE在DatePickerFragment的第39行上。它为空的原因是当方向改变时,整个视图层次结构会被重新创建,并且传递给DatePickerFragment的TextView引用不再存在。

尝试传递TextView的ID而不是实例。

new DatePickerFragment(v.getId());

然后实施

public Bundle onSaveInstanceState ()

并且

public void onRestoreInstanceState (Bundle savedInstanceState)

为了保留并恢复 TextView 的 ID,在 DatePickerDialog 被销毁和重建时使用。

然后您需要使用

getActivity().findViewById(your_text_view_ID)

在视图层次结构中查找您的TextView实例,以便您可以设置其文本。

1
我同意。当Android重建您的片段时,它会调用默认构造函数(public DatePickerFragment() {})...引用文档中的话,“所有Fragment的子类都必须包含一个公共的空构造函数。在需要时,框架经常重新实例化片段类,特别是在状态恢复期间,并且需要能够找到此构造函数来实例化它。” - Sam
@Akos Cz:我知道为什么会出现这种情况。我想通过修改代码来克服这种情况。你能帮我解决如何将这个TextView ID传递到Fragment吗? - Bhavesh Patadiya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接