Fragment

时间:2015-10-26 11:57:25

标签: android android-fragments

我最近一直在努力应对配置更改并在我的应用中保存片段中的状态。我通过在我的片段中覆盖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);
}

}

2 个答案:

答案 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中,它并没有从中失去焦点。