如何避免Picker Fragment在方向更改时再次启动?

时间:2015-09-05 17:22:33

标签: android android-fragments datepicker

我有一个正常工作的DatePicker片段,直到发生方向更改。用户单击UI屏幕上的EditText行并启动DatePcker片段。用户选择日期,代码在EditText行上设置日期。使用闪烁的光标将焦点返回到EditText行。

虽然在方向更改时,代码会启动DatePicker片段的对话框,而不是使用闪烁的光标将焦点返回到EditText行。更改前的先前设置日期已正确保留并显示在EditText行上。我只想将光标设置在EditText行的末尾,而不是再次启动DatePicker片段。请指教。

部分活动文件:

    ...
    fListenerEditText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            DialogFragment newFragment = new DatePickerFragment();
            newFragment.show(getSupportFragmentManager(), "datePicker");
            fListenerEditText.requestFocus();
        }
    });

    fListenerEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                DialogFragment newFragment = new DatePickerFragment();
                newFragment.show(getSupportFragmentManager(), "datePicker");
                fListenerEditText.requestFocus();
            }
        }
    });

DatePickerFragment文件:

...
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

private EditText txtDate;
private Calendar cal;
private int currentyear;
private int currentmonth;
private int currentday;
private String stringDueDateFrag;

// Empty, parameterless constructor required for DialogFragment that is used by the OS to
// recreate the fragment on device orientation changes.
public DatePickerFragment() {
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    // Use the current date as the default date that we get from a Calendar object, in the DatePicker Dialog.
    cal = Calendar.getInstance();
    currentyear = cal.get(Calendar.YEAR);
    currentmonth = cal.get(Calendar.MONTH);
    currentday = cal.get(Calendar.DAY_OF_MONTH);

    // Create a new instance of DatePickerDialog by passing 5 parameters/arguments to the constructor and return it.
    DatePickerDialog dialog = new DatePickerDialog(getActivity(),this,currentyear,currentmonth,currentday);
    dialog.getDatePicker().setCalendarViewShown(true);
    dialog.getDatePicker().setSpinnersShown(false);
    dialog.setTitle("Select a Due Date");

    return dialog;
}

    public void onDateSet (DatePicker view,int year, int month, int day) {
    txtDate = (EditText) getActivity().getWindow().getDecorView().getRootView().findViewById(R.id.FEditText);
    stringDueDateFrag = (month + 1) + "/" + day + "/" + year + " ";
    txtDate.setText(stringDueDateFrag);
    txtDate.setSelection(txtDate.getText().length());
}

    public void onDismiss(final DialogInterface dialog) {
    InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(CardViewActivity.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

    super.onDismiss(dialog);
    }
}

2 个答案:

答案 0 :(得分:1)

在方向更改期间,将重新创建Activity并设置焦点。显然,您的OnFocusChangeListener被调用以将焦点设置在EditText视图上。

如果您只希望在EditText为空时显示对话框,请尝试更改onFocusChange()以包含空虚测试。无论何时,只要焦点返回EditText,您就需要进行此类测试。

fListenerEditText.setOnFocusChangeListener(new OnFocusChangeListener() { 
    @Override 
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus && (fListenerEditText.getText().length() == 0) {
            DialogFragment newFragment = new DatePickerFragment(); 
            newFragment.show(getSupportFragmentManager(), "datePicker"); 
            fListenerEditText.requestFocus(); 
        } 
    } 
}); 

答案 1 :(得分:0)

public class MainActivity extends ActionBarActivity {

    boolean isActivityLoaded = false;
    static String IS_ACTIVITY_LOADED = "IS_ACTIVITY_LOADED";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        outState.putBoolean(IS_ACTIVITY_LOADED,true);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        isActivityLoaded = savedInstanceState.getBoolean(IS_ACTIVITY_LOADED);
    }

    // SOme place where you are doing the fragment transaction
    void fragmentTransaction() {
        if(!isActivityLoaded) {
            // Dont do transaction.
        }
    }

}