单击我的(Scherlock)FragmentActivity中的EditText字段时,会显示一个DatePicker。选择日期并单击“应用”后,将使用日期填充Edittext字段。这可以正常工作,直到我在DatePicker可见时旋转屏幕。它的onCreateDialog方法再次启动,一切看起来都正确。但是,当我单击“应用”时,EditText字段中没有填写任何日期。
这很可能是因为我没有设法保留听众。这个问题与DialogFragment - retaining listener after screen rotation非常相似但是在我的代码中我有一个DialogFragment中包含的监听器接口,我无法通过调用FragmentActivity来达到监听器(正如解决方案在上述问题中所建议的那样)。
请帮助我,这真的不应该那么难,但我一直在使用它的时间比我承认的还要长......
这是DialogFragment代码:
public class DateDialogFragment extends SherlockDialogFragment {
public static String TAG = "DateDialogFragment";
static Context mContext;
static int mYear;
static int mMonth;
static int mDay;
static DateDialogFragmentListener mListener;
public static DateDialogFragment newInstance(Context context, DateDialogFragmentListener listener, Calendar now) {
DateDialogFragment dialog = new DateDialogFragment();
mContext = context;
mListener = listener;
mYear = now.get(Calendar.YEAR);
mMonth = now.get(Calendar.MONTH);
mDay = now.get(Calendar.DAY_OF_MONTH);
return dialog;
}
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new DatePickerDialog(mContext, mDateSetListener, mYear, mMonth, mDay);
}
private OnDateSetListener mDateSetListener = new OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
mListener.updateChangedDate(year, monthOfYear, dayOfMonth);
}
};
public interface DateDialogFragmentListener {
public void updateChangedDate(int year, int month, int day);
}
}
编辑:这是我的FragmentActivity的一部分:我用来调用DialogFragment的方法:
public void showDatePickerDialog() {
now = Calendar.getInstance();
DateDialogFragment frag = DateDialogFragment.newInstance(
this, new DateDialogFragment.DateDialogFragmentListener() {
public void updateChangedDate(int year, int month, int day) {
birthdate.setText(String.valueOf(day) + "-" + String.valueOf(month+1) + "-" + String.valueOf(year));
now.set(year, month, day);
pet.setBirthdate(birthdate.getText().toString());
}
},
now);
frag.show(getSupportFragmentManager(), "DateDialogFragment");
}
答案 0 :(得分:6)
我遇到了同样的问题。这是解决方案,from Luksprog。它对我来说很完美。
if (savedInstanceState != null) {
DatePickerFragment dpf = (DatePickerFragment) getSupportFragmentManager()
.findFragmentByTag("theTag?");
if (dpf != null) {
dpf.setListener(listener);
}
}
并且不需要像上面的答案那样包裹片段......
答案 1 :(得分:3)
在朋友的帮助下,我现在可以解决这个问题。简短版本是:使DateDialogFragment可分区并在方向更改时保存片段。每次onCreate在调用类中运行时重新创建监听器。正如您所看到的那样,showDatePickerDialog()已更改,以便将侦听器的创建移出它。
以下是一些片段,从调用类开始:
DateDialogFragment frag;
DateDialogFragment.DateDialogFragmentListener mListener;
private EditText birthdate;
private Calendar now;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mListener = new DateDialogFragment.DateDialogFragmentListener() {
@Override
public void updateChangedDate(int year, int month, int day) {
now.set(year, month, day);
pet.setBirthdate(now.getTimeInMillis());
birthdate = (EditText) findViewById(R.id.birth_day_et);
birthdate.setText(pet.getBirthdateInText());
}
};
if (savedInstanceState != null) {
pet.setBirthdate(savedInstanceState.getLong("birthday"));
now = (Calendar) savedInstanceState.getSerializable("n");
if (now != null) {
frag = (DateDialogFragment) savedInstanceState.getParcelable("frag");
frag.setListener(mListener);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("birthday", pet.getBirthdateInMillis());
outState.putSerializable("n", now);
outState.putParcelable("frag", frag);
}
}
public void showDatePickerDialog() {
now = Calendar.getInstance();
frag = DateDialogFragment.newInstance(this, mListener, now);
frag.show(getSupportFragmentManager(), "DateDialogFragment");
}
以下是DateDialogFragment类的更改。除了下面写的内容,该课程与我的问题相同。
public class DateDialogFragment extends SherlockDialogFragment implements Parcelable {
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel arg0, int arg1) {
}
public static void setListener(DateDialogFragmentListener listener) {
mListener = listener;
}
在调用类中重新创建侦听器的解决方案可能不是最可能的,但至少它可以工作。我希望这对某人有用。 :)