我最近一直在努力应对配置更改并在我的应用中保存片段中的状态。我通过在我的片段中覆盖onSaveInstanceState来获得一些片段(我不知道这是可能的,我之前做过这是我的MainActivity)。
我正在使用一个带有许多片段的MainActivity,目前正在发生的事情是当我显示Fragment1并打开一个DatePickerFragment时,这是Fragment1上显示的对话框,我松开了Fragment1中输入的数据旋转屏幕。
我已经使用onSaveInstanceState方法在Fragment1中保存状态,当我只有Fragment1可见时旋转设备时,没有数据丢失。只有当DatePickerFragment被创建并且可见并且我旋转手机时,数据才会丢失。
我会举个例子: 在Fragment1中,我可以选择一个日期并在两个字段中输入文本。 我在文本字段中输入“blabla”。 现在我想输入一个日期,所以我点击一个按钮打开DatePickerFragment,我选择一个日期,然后我旋转我的设备。 我单击“设置”,然后查看我的Fragment1,其中“blabla”现在消失,我的文本字段为空(Fragment1没有通过保存状态)。
这是我的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);
}
}
答案 0 :(得分:0)
因为当您更改方向时,再次调用onCreate方法。因此,在这种情况下,您必须覆盖方法 public void onSaveInstanceState(Bundle savedInstanceState)和public void onRestoreInstanceState(Bundle savedInstanceState)。
您必须将数据保存在savedInstanceState和 在RestoreInstanceState方法中接收数据。
答案 1 :(得分:-3)
您可以通过在Activity
android:configChanges="orientation|screenSize" Activity Flags
来阻止您的manifest.xml
重新加载,然后重新加载您的片段
如果您执行此操作并且想要更改任何视图参数,仍可以通过覆盖 public void onConfigurationChanged(Configuration newConfig)
例如 whatsapp 在其聊天视图中执行此操作:
当您正在编写消息然后旋转屏幕时,它会保留文本
在EditTextView
中,它并没有从中失去焦点。