簡體   English   中英

片段方向改變時數據丟失

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM