android开发之Fragment利用Bundle保存状态

相信很多小伙伴们在使用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在另一个教程讲解




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值