【问题标题】:How to use onSaveInstanceState and onRestoreInstanceState methods with fragments?如何在片段中使用 onSaveInstanceState 和 onRestoreInstanceState 方法?
【发布时间】:2013-10-29 12:03:12
【问题描述】:

我有两个Fragments。其中一个有一个EditText 和一个Button。另一个只有一个ListViewListView中的数据如何保存,以防模拟器方向发生变化?

我的问题是,当我旋转模拟器的屏幕时,我不知道如何保存和恢复我的ListViewonSaveInstanceStateonRestoreInstanceState 方法应该放在哪里以及如何使用它们?

MainActivity.java

    public class MainActivity extends Activity implements AddToDoFragment.OnToDoAddedListener {

private ArrayList<String> todoItems;
private ArrayAdapter<String> adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FragmentManager fm = getFragmentManager();

    ToDoListFragment listToDo = new ToDoListFragment();
    listToDo = (ToDoListFragment) fm.findFragmentById(R.id.list_view_fragment);
    todoItems = new ArrayList<String>();
    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems);
    listToDo.setListAdapter(adapter);
}

public void OnToDoAdded(String newToDo) {
    todoItems.add(newToDo);
    adapter.notifyDataSetChanged();

}

AddToDoFragment.java

public class AddToDoFragment extends Fragment {

public interface OnToDoAddedListener {

    public void OnToDoAdded (String newToDo);

}

private OnToDoAddedListener onToDoAddedListener;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        final Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.add_to_do_fragment, container, false);

    final EditText edittext = (EditText) view.findViewById(R.id.editText);
    final Button button = (Button) view.findViewById(R.id.addButton);
    button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            String text = edittext.getText().toString();
            onToDoAddedListener.OnToDoAdded(text);
            edittext.setText("");
        }
    });

    return view;

}

 @Override
    public void onAttach(Activity activity) {
      super.onAttach(activity);
      if (activity instanceof OnToDoAddedListener) {
        onToDoAddedListener = (OnToDoAddedListener) activity;
      } else {
        throw new ClassCastException(activity.toString()
            + " must implemenet AddToDoFragment.OnToDoAddedListener");
      }
    }
   }

ToDoListFragment.java

public class ToDoListFragment extends ListFragment {
}

【问题讨论】:

    标签: java android listview android-fragments onrestoreinstancestate


    【解决方案1】:

    您需要覆盖活动的onSaveInstanceState 方法,以便知道何时需要保存状态。然后您还需要更新您的onCreate 方法以检查savedInstanceState 是否为null。如果是null,则该活动尚未启动。这是您的 MainActivity 课程的示例,您可以从那里开始:

    MainActivity.java

    public class MainActivity extends Activity implements AddToDoFragment.OnToDoAddedListener {
    
    private ArrayList<String> todoItems;
    private ArrayAdapter<String> adapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        if(savedInstanceState == null) {
            todoItems = new ArrayList<String>();
        } else {
            todoItems = savedInstanceState.getStringArrayList("todoItemTag");//the tag must match what the variable was saved with
        }
    
        FragmentManager fm = getFragmentManager();
    
        ToDoListFragment listToDo = new ToDoListFragment();
        listToDo = (ToDoListFragment) fm.findFragmentById(R.id.list_view_fragment);
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems);
        listToDo.setListAdapter(adapter);
    }
    
    public void OnToDoAdded(String newToDo) {
        todoItems.add(newToDo);
        adapter.notifyDataSetChanged();
    
    }
    
    //Saving the instance by overriding this function
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    
        outState.putStringArrayList("todoItemTag", todoItems);//it would be advised to make the tags a static final String
    }
    

    希望这会有所帮助!

    PS:我不认为onRestoreInstanceState 方法真的很有必要。我想我以前从未使用过它。我相信您应该能够在onCreate 方法中使用null 检查提供相同的功能。

    【讨论】:

    • 感谢您的关注,但不幸的是我出错了 Bundle 类型中的 putParcelableArrayList(String, ArrayList extends Parcelable>) 方法不适用于参数 (String, ArrayList)
    • 以及 getParcelableArrayList 方法也会给出类似 Bound mismatch 的错误:Bundle 类型的通用方法 getParcelableArrayList(String) 不适用于参数 (String)。推断的类型 String 不是有界参数 的有效替代品
    • 查看我的新编辑。您将需要使用 get/set StringArrayList 而不是 ParcelableArrayList
    • 我应用了您的建议,但仍然无法正常工作。当我旋转模拟器屏幕时,以前的列表视图数据会丢失。还有什么建议吗?
    • ooovvv 好的,我看到了我缺少的东西,我重新创建了我的数组列表,因此每次试验都显示空列表。当我删除该行时,它可以完美运行。再次感谢您...
    猜你喜欢
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    相关资源
    最近更新 更多