4

单击我的 (Scherlock)FragmentActivity 中的 EditText 字段时,会显示 DatePicker。选择日期并单击“应用”后,Edittext 字段将填充日期。这工作正常,直到我在 DatePicker 可见时旋转屏幕。它的 onCreateDialog 方法再次启动,一切正常。但是当我单击“应用”时,EditText 字段中没有填写任何日期。

这很可能是因为我没有设法留住听众。这个问题非常类似于DialogFragment - 在屏幕旋转后保留侦听器但是在我的代码中,我有一个包含在 DialogFragment 中的侦听器接口,我无法设法从调用 FragmentActivity 到达侦听器(正如上述问题中的解决方案所建议的那样)。

  • 我想不是,但是有没有办法在活动被破坏之前保存监听器?(我对 Manifest 修改不感兴趣。)
  • 有没有办法修改这个 DialogFragment 或者这个包含接口的解决方案不适合这种情况?

请帮助我,这真的不应该那么难,但我使用它的时间比我承认的要长......

这是 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");   
}   
4

2 回答 2

8

我遇到了同样的问题。这是来自 Luksprog的解决方案。它非常适合我。

if (savedInstanceState != null) {
    DatePickerFragment dpf = (DatePickerFragment) getSupportFragmentManager()
            .findFragmentByTag("theTag?");
    if (dpf != null) {
        dpf.setListener(listener);
    }
}

并且不需要像上面的答案中提到的那样打包片段......

于 2013-11-26T08:28:21.980 回答
4

在朋友的帮助下,我现在有了解决这个问题的方法。简短的版本是:使 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;
}

在调用类中重新创建侦听器的解决方案可能不是最漂亮的,但至少它有效。我希望这对某人有用。:)

于 2013-11-04T17:05:14.230 回答