[英]Data is lost on orientation change on Fragment
我最近一直在努力進行配置更改,並將狀態保存在應用程序的片段中。 通過覆蓋片段中的onSaveInstanceState,我得到了一些片段(我不知道有可能,我之前是MainActivity)。
我正在使用一個具有許多片段的MainActivity,目前正在發生的事情是,當我顯示我的Fragment1並打開DatePickerFragment時,這是在Fragment1上顯示的對話框,當我旋轉屏幕時,我會丟失在Fragment1中輸入的數據。
我已經通過使用onSaveInstanceState方法將狀態保存在Fragment1中,當僅可見Fragment1時旋轉設備時,沒有數據丟失。 僅當創建並且可見DatePickerFragment並且旋轉手機時,數據才會丟失。
我舉一個例子:在Fragment1中,我可以選擇一個日期並在兩個字段中輸入文本。 我在文本字段中輸入“ blabla”。 現在我想輸入一個日期,因此我單擊了一個打開DatePickerFragment的按鈕,選擇了一個日期,然后旋轉設備。 單擊“設置”,然后查看“ blabla”現在消失的“片段1”,並且我的文本字段為空(“片段1”未通過保存狀態)。
這是我的Fragment1代碼:
public class GoalFragment extends Fragment {
private ImageButton edit_weight, edit_date;
private ToggleButton goal_type_toggle;
private TextView mWeightValue, mDateValue;
private Button mSaveButton;
private DatePicker mDatePicker;
private Calendar calendar;
private float weight_goal;
private Date date_goal;
private int selectedConstant;
private float convertedFloat;
private boolean didSetWeight = false;
private boolean didSetDate = false;
final static int DATE_PICKER_ID = 0;
private int mYear, mMonth, mDay;
public static Date SELECTED_DATE;
public static float SELECTED_WEIGHT;
public static boolean isLoose = true;
public static float ENTERED_WEIGHT;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
super.onCreateView(inflater, parent, savedInstanceState);
View view = inflater.inflate(R.layout.goal_fragment, parent, false);
setHasOptionsMenu(true);
//Intialize view elements
edit_weight = (ImageButton) view.findViewById(R.id.button_change_goal);
edit_date = (ImageButton) view.findViewById(R.id.button_change_goal_date);
goal_type_toggle = (ToggleButton) view.findViewById(R.id.goal_switch);
mWeightValue = (TextView) view.findViewById(R.id.your_goal_value);
mDateValue = (TextView) view.findViewById(R.id.your_goal_date_value);
mSaveButton = (Button) view.findViewById(R.id.save_goal_btn);
mSaveButton.setEnabled(false);
//attempt to restore data on rotation with bundle as arguments
Bundle restoreBundle = getArguments();
if (restoreBundle != null) {
float restored_weight = restoreBundle.getFloat("goal_weight");
String weight_value = Float.toString(restored_weight);
mWeightValue.setText(weight_value);
} else {
initializeGoalData();
}
mSaveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Goal goal = new Goal(convertedFloat, SELECTED_DATE, isLoose);
WeighInLab.get(getActivity()).createNewRealmGoal(goal);
}
});
edit_weight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showWeightEditor();
}
});
edit_date.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDatePicker();
}
});
goal_type_toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
isLoose = false;
} else {
isLoose = true;
}
}
});
return view;
}
//Get goal data from internal storage if goal data has been set before (if it exists in storage)
public void initializeGoalData() {
Goal goal = WeighInLab.get(getActivity()).getGoal();
if (goal == null) {
mWeightValue.setText("");
mDateValue.setText("");
} else {
mWeightValue.setText(Float.toString(goal.getWeight()) + " KG");
mWeightValue.setTextColor(getResources().getColor(R.color.green_2));
SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd yyyy");
String dateString = sdf.format(goal.getDate());
mDateValue.setText(dateString);
if (goal.isLoose()) {
goal_type_toggle.setChecked(false);
} else {
goal_type_toggle.setChecked(true);
}
}
}
//Show datepicker using a datepickerfragment see DatePickerFragment
private void showDatePicker() {
DatePickerFragment dpfragment = new DatePickerFragment();
Calendar calendar = Calendar.getInstance();
Bundle args = new Bundle();
args.putInt("year", calendar.get(Calendar.YEAR));
args.putInt("month", calendar.get(Calendar.MONTH));
args.putInt("day", calendar.get(Calendar.DAY_OF_MONTH));
dpfragment.setArguments(args);
dpfragment.setCallBack(ondate);
dpfragment.show(((MainActivity) getActivity()).getFragmentManager(), null);
}
DatePickerDialog.OnDateSetListener ondate = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
Calendar cal = Calendar.getInstance();
cal.set(year, monthOfYear, dayOfMonth);
SELECTED_DATE = cal.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd yyyy");
String dateString = sdf.format(SELECTED_DATE);
mDateValue.setText(dateString);
didSetDate = true;
enableSaveIfDataEntered();
}
};
//Show weight editor as a dialog
public void showWeightEditor() {
final Dialog d = new Dialog(getActivity());
d.setTitle("Goal weight");
d.setContentView(R.layout.weight_picker_dialog);
Button button_cancel = (Button) d.findViewById(R.id.button_cancel);
Button button_set = (Button) d.findViewById(R.id.button_set);
final NumberPicker np_constant = (NumberPicker) d.findViewById(R.id.numberPicker_constant);
final NumberPicker np_decimal = (NumberPicker) d.findViewById(R.id.numberPicker_decimal);
TextView mDialogText = (TextView) d.findViewById(R.id.weight_edit_dialog_text);
mDialogText.setText("Enter your goal weight");
//Config numberpicker for constant
np_constant.setMaxValue(100); // max value 100
np_constant.setMinValue(0); // min value 0
np_constant.setWrapSelectorWheel(false);
np_constant.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldValb, int newValb) {
selectedConstant = picker.getValue();
}
});
final String[] decimals = {".0", ".1", ".2", ".3", ".4", ".5", ".6", ".7", ".8", ".9"};
//Config numberpicker for decimals
np_decimal.setMaxValue(decimals.length - 1); // max value 100
np_decimal.setMinValue(0); // min value 0
np_decimal.setWrapSelectorWheel(false);
np_decimal.setDisplayedValues(decimals);
np_decimal.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldValb, int newValb) {
int index = picker.getValue();
String val = decimals[index];
SELECTED_WEIGHT = Float.parseFloat(val);
}
});
button_set.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Float tempfloat = new Float(selectedConstant);
convertedFloat = tempfloat + SELECTED_WEIGHT;
String s = Float.toString(convertedFloat);
mWeightValue.setText(s + " KG");
ENTERED_WEIGHT = convertedFloat;
mWeightValue.setTextColor(getResources().getColor(R.color.green_2));
didSetWeight = true;
enableSaveIfDataEntered();
d.dismiss();
}
});
button_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
}
});
if (didSetWeight) {
np_constant.setValue(selectedConstant);
String s = Float.toString(SELECTED_WEIGHT);
int index = Arrays.asList(decimals).indexOf(s);
np_decimal.setValue(index);
}
d.show();
}
//Enable save button if any data was entered
public void enableSaveIfDataEntered() {
if (didSetDate && didSetWeight) {
mSaveButton.setEnabled(true);
} else {
mSaveButton.setEnabled(false);
}
}
@Override
public void onResume() {
super.onResume();
// Set title
getActivity().setTitle("Goal weight");
}
}
這是我的DatePickerFragment代碼:
public class DatePickerFragment extends DialogFragment {
private DatePickerDialog.OnDateSetListener ondateSet;
private int year, month, day;
public DatePickerFragment() {
}
public void setCallBack(DatePickerDialog.OnDateSetListener ondate) {
ondateSet = ondate;
}
@Override
public void setArguments(Bundle args) {
super.setArguments(args);
year = args.getInt("year");
month = args.getInt("month");
day = args.getInt("day");
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new DatePickerDialog(getActivity(), ondateSet, year, month, day);
}
}
因為在更改方向時會再次調用onCreate方法。 因此,在這種情況下,您必須重寫方法public void onSaveInstanceState(Bundle savedInstanceState)和public void onRestoreInstanceState(Bundle savedInstanceState)。
您必須將數據保存在bundle中的savedInstanceState中,並使用RestoreInstanceState方法接收數據。
您可以防止您的Activity
從重裝並依次通過設置以下刷新你的片段android:configChanges="orientation|screenSize" Activity Flags
在你manifest.xml
如果您這樣做並且想要更改任何視圖參數,則仍然可以通過重寫 public void onConfigurationChanged(Configuration newConfig)
例如,這是whatsapp在其聊天視圖中執行的操作:在編寫消息然后旋轉屏幕時,它將文本保留在EditTextView
,並且不會因此而失去焦點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.