相信很多小伙伴们在使用Fragment都会遇到状态保存的问题,今天介绍一个简单的案例。
大家都知道在使用Activity之间传递数据时大部分情况下都是用Bundle;
先帮大家复习一下Bundle,利用键值对(key-value)来存储数据的,内部包含ArrayMap<String, Object> mMap = null;
1. 新建一个Bundle类:
Bundle mBundle = new Bundle();
2. Bundle可以储存的数据类型:
mBundle.putInt("key1", 1);
mBundle.putString("key2", "测试");
mBundle.putParcelable("key3", user);
基本数据类型和对象数据类型【user implements Parcelable】
3. Activity传递数据:
Intent mIntent = new Intent(this, MnScaleBarActivity.class);
mIntent.putExtra("data", mBundle);
startActivity(mIntent);
Ok,现在来说说Fragment与Bundle
在Fragment中有两个方法:
/**
* Supply the construction arguments for this fragment. This can only
* be called before the fragment has been attached to its activity; that
* is, you should call it immediately after constructing the fragment. The
* arguments supplied here will be retained across fragment destroy and
* creation.
*/
public void setArguments(Bundle args) {
if (mIndex >= 0) {
throw new IllegalStateException("Fragment already active");
}
mArguments = args;
}
/**
* Return the arguments supplied when the fragment was instantiated,
* if any.
*/
final public Bundle getArguments() {
return mArguments;
}
1. 在Fragment的子类调用getArguments()获取Bundle对象,获取对象如果为null可以新建Bundle调用setArguments()重新设置
2. 新建Fragment子类StateFragment
public class StateFragment extends Fragment{
private Bundle saveState;
private String tag = StateFragment.class.getSimpleName();
public StateFragment(){
super();
if(getArguments() == null){
setArguments(new Bundle());
}
}
}
3. 子类重写父类方法onSaveInstanceState()和OnDestoryView()进行保存数据:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveStateToArguments();
}
@Override
public void onDestroyView() {
super.onDestroyView();
saveStateToArguments();
}
4. 保存状态saveStateToArguments()
private void saveStateToArguments(){
if(getView() != null){
saveState = saveState();
}
if(saveState != null){
Bundle b = getArguments();
if(b!=null){
b.putBundle("internalSavedViewState8954201239547", saveState);
}
}
}
4.1 供子类调用的状态保存方法
/**
* 保存状态
* */
private Bundle saveState(){
Bundle state = new Bundle();
//保存数据
onSaveState(state);
return state;
}
/**
* 子类重写该方法实现状态保存
* */
public void onSaveState(Bundle outState){
}
5. 恢复状态restoreStateArguments()
private boolean restoreStateFromArguments(){
Bundle b = getArguments();
if(b == null) return false;
saveState = b.getBundle("internalSavedViewState8954201239547");
if(saveState != null){
restoreState();
return true;
}
return false;
}
5.1 供子类恢复状态的方法
/**
* 恢复状态
* */
private void restoreState(){
if(saveState != null){
onRestoreState(saveState);
}
}
/**
* 子类重写该方法恢复状态
* */
public void onRestoreState(Bundle saveInstanceState){
}
源码如下:
package cc.mntabdemo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* User: 山野书生(1203596603@qq.com)
* Date: 2015-11-27
* Time: 15:21
* Version 1.0
*/
public class StateFragment extends Fragment{
private Bundle saveState;
private String tag = StateFragment.class.getSimpleName();
public StateFragment(){
super();
if(getArguments() == null){
setArguments(new Bundle());
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(!restoreStateFromArguments()){
onFirstTimeLaunched();
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveStateToArguments();
}
@Override
public void onDestroyView() {
super.onDestroyView();
saveStateToArguments();
}
/**
* 第一次加载该类
* */
public void onFirstTimeLaunched(){
}
private void saveStateToArguments(){
if(getView() != null){
saveState = saveState();
}
if(saveState != null){
Bundle b = getArguments();
if(b!=null){
b.putBundle("internalSavedViewState8954201239547", saveState);
}
}
}
private boolean restoreStateFromArguments(){
Bundle b = getArguments();
if(b == null) return false;
saveState = b.getBundle("internalSavedViewState8954201239547");
if(saveState != null){
restoreState();
return true;
}
return false;
}
/**
* 恢复状态
* */
private void restoreState(){
if(saveState != null){
onRestoreState(saveState);
}
}
/**
* 子类重写该方法恢复状态
* */
public void onRestoreState(Bundle saveInstanceState){
}
/**
* 保存状态
* */
private Bundle saveState(){
Bundle state = new Bundle();
//保存数据
onSaveState(state);
return state;
}
/**
* 子类重写该方法实现状态保存
* */
public void onSaveState(Bundle outState){
}
}
子类:
package cc.mntabdemo;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* User: 山野书生(1203596603@qq.com)
* Date: 2015-11-26
* Time: 16:26
* Version 1.0
*/
public class ContentFragment extends StateFragment {
private TextView text;
private Button btn;
private EditText edit;
private String mTitle;
private String tag = ContentFragment.class.getSimpleName();
public ContentFragment(){
super();
}
public ContentFragment(String title){
super();
mTitle = title;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_content_layout, container, false);
return rootView;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initViews(view);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
text.setText(edit.getText().toString());
}
});
}
private void initViews(View view){
text = (TextView)view.findViewById(R.id.text);
btn = (Button)view.findViewById(R.id.btn);
edit = (EditText)view.findViewById(R.id.edit);
}
@Override
public void onRestoreState(Bundle saveInstanceState) {
edit.setText(saveInstanceState.getString("edit"));
text.setText(saveInstanceState.getString("text"));
}
@Override
public void onSaveState(Bundle outState) {
outState.putString("edit", edit.getText().toString());
outState.putString("text", text.getText().toString());
}
}
布局代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edit"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送"
android:id="@+id/btn"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/text"
/>
</LinearLayout>
EditText自身可以保存以及恢复
感谢开源项目:StatedFragment
本项目源码:源码
本Demo在MnTabDemo基础上完成,包含【高仿微信6.0底部Tab和StatedFragment】;
高仿微信6.0底部Tab在另一个教程讲解