更改屏幕方向后,片段中的TextView内容将丢失

时间:2014-08-04 16:03:41

标签: android textview fragment

按照标题,&这是我的代码的一部分:

public class ExpensesDaily extends Fragment{

    private int selectedYear, selectedMonth, selectedDay;
    private String displaySelectedDate;
    public ExpensesDaily(){}
    TextView tvDate;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

        super.onActivityCreated(savedInstanceState);

        if (savedInstanceState != null){
            if (savedInstanceState.getString("displaySelectedDate") != null){
                String data = savedInstanceState.getString("displaySelectedDate");
            Toast.makeText(getActivity(), "data state saved" + data, Toast.LENGTH_LONG).show();
                tvDate = (TextView) getActivity().findViewById(R.id.tvSelectedDate);
                tvDate.setText(data);
            }
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){

        View rootView = inflater.inflate(R.layout.expenses_daily, container, false);

        ImageButton imgBtnChangeDate = (ImageButton) rootView.findViewById(R.id.imgBtnChangeDate);
        imgBtnChangeDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DatePickerFragment dpf = new DatePickerFragment().newInstance();
                dpf.setCallBack(onDate);
                dpf.show(getFragmentManager().beginTransaction(), "DatePickerFragment");
            }
        });
        return rootView;
    }

    DatePickerDialog.OnDateSetListener onDate = new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear,
                              int dayOfMonth) {

            displaySelectedDate = String.valueOf(year) + "-" + String.valueOf(monthOfYear)
                    + "-" + String.valueOf(dayOfMonth);
            tvDate = (TextView) getActivity().findViewById(R.id.tvSelectedDate);
            tvDate.setText(displaySelectedDate);
        }
    };

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putString("displaySelectedDate", displaySelectedDate);
    }
}

在我的TextView tvDate中成功设置了一个值并且我更改了方向后,logcat将返回此错误

Caused by: java.lang.NullPointerException at ExpensesDaily.onCreate(ExpensesDaily.java:38)

指向此行

tvDate.setText(data);

知道为什么该行触发了nullpointerexception错误?

更新:在user3249477的回答之后,NPE错误不再出现。但是,文本视图仍未使用保存的数据进行更新。

更多信息:我之前应该知道这一点(最初我认为它对我的问题没有任何影响),类ExpensesDaily是另一个片段NavigationDrawerFragment中的一个片段。我的项目使用NavigationDrawer项目,该项目是在Android Studio中选择NavigationDrawer项目时自动创建的。

2 个答案:

答案 0 :(得分:1)

请不要在片段的onCreate中使用getActivity

而是在创建活动时使用它(在片段的onActivityCreated内)。

那是因为片段可以在活动之前创建,然后getActivity方法将返回null,因此 NPE

答案 1 :(得分:0)

阅读完本文http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html后,我似乎错过了保留片段中对象的最重要部分:

setRetainInstance(true);

无论如何,我首先把代码设置为setRetainInstance(true);在我的ExpensesDaily.java中,但我会收到错误

FATAL EXCEPTION: main java.lang.IllegalStateException: Can't retain fragements that are nested in other fragments

但是当我把代码设置为setRetainInstance(true)时;在NavigationDrawerFragment.java里面的onCreate()里面,我的问题解决了。

所以我希望我在这里的简单冒险可以帮助其他人解决同样的问题。