1. 程式人生 > >android開發之Fragment利用Bundle儲存狀態

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: 山野書生([email protected])
 * 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: 山野書生([email protected])
 * 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自身可以儲存以及恢復



本專案原始碼:原始碼
本Demo在MnTabDemo基礎上完成,包含【高仿微信6.0底部Tab和StatedFragment】;

高仿微信6.0底部Tab在另一個教程講解

相關推薦

android開發Fragment利用Bundle儲存狀態

相信很多小夥伴們在使用Fragment都會遇到狀態儲存的問題,今天介紹一個簡單的案例。 大家都知道在使用Activity之間傳遞資料時大部分情況下都是用Bundle; 先幫大家複習一下Bundle,利用鍵值對(key-value)來儲存資料的,內部包含ArrayMap<

android開發fragment與activity之間相互跳轉

   Fragment的產生與介紹 Android執行在各種各樣的裝置中,有小螢幕的手機,超大屏的平板甚至電視。針對螢幕尺寸的差距,很多情況下,都是先針對手機開發一套App,然後拷貝一份,修改佈局以適應平板神馬超級大屏的。難道無法做到一個App可以同時適應手機和平板麼

Android開發Fragment

前幾篇博文給大家介紹了Android的四大元件,今天給大家介紹一下Android開發中常用的Fragment,也被稱作碎片。在開發中,Fragment使用極其廣泛,像微信的主介面,淘寶,等等。。很多很多都是使用了Framgent。 Fragment是依賴於Activity存

Android開發監聽軟鍵盤狀態(彈出收回)

概述 如何使用 隱患 概述 在我們開發過程中,有時需要監聽手機軟鍵盤狀態,但是Android沒有這樣的API,所以需要我們自己處理。 實現方案 實現效果與原理 先上一張效果圖 可以看到我們準確的監聽到了軟鍵盤的彈出與收起事

Android開發 動態顯示和隱藏狀態列和導航欄

// //佈局填充狀態列,設定透明 // if (Build.VERSION.SDK_INT >= 21) { // View decorView = getWindow().getDecorView(); // int optio

android開發利用SharedPreferences儲存字串陣列

1.Android3.0之後,SharedPreferences提供了putStringSet方法,可以儲存字串陣列,例子: SharedPreferences sp = mContext.getSharedPreferences("data", Context.MO

Android開發Fragment切換優化

rst 心得 getc format ref pri 就是 rip eight 問題分析 一直在簡書裏看別人的技術貼,今天我也來寫點自己的心得!最近在寫一個項目用到大量的Fragment後的總結! 我想剛剛接觸安卓的同學或許會這麽寫: FragmentManager

Android開發應用狀態列、導航欄都透明

  直接上程式碼 //狀態列、導航欄都透明 private void hideStatusBarNavigationBar() { if (Build.VERSION.SDK_INT = Build.VERSION_CODES.LOLLIPOP)

Android開發獲取手機硬體狀態資訊(CPU資訊/頻率/使用率、DDR頻率/使用率、電池瞬時電流/電壓/庫倫counter)

有時候我們想要知道當前手機的一些狀態資訊,可以使用app(root 或者系統簽名 )來顯示獲取。 OK,接下來看一下一些關鍵的程式碼。 我這裡使用的是高通的手機,不同硬體平臺的機型,其獲取資訊的節點可能不一樣。 /** * 獲取當前瞬時電流

android開發應用Crash自動抓取Log_自動儲存崩潰日誌到本地

應用發生crash之後要檢視log,判斷問題出在什麼地方,可是一旦應用釋出出去,就要想辦法把使用者的崩潰日誌拿到分析。所以要在發生crash之後抓取log,然後上傳到伺服器,方便開發者檢視,現在都有很多第三方做這方面的服務,這裡說下如何自己來實現。其實原理很簡單,應用出現異常

android開發利用百度助手平臺升級

   版本檢測升級是Android開發中不可缺少的下面我們利用第三方來進行版本的升級: (1)登陸百度助手釋出平臺 地址:http://app.baidu.com/ 在自動更新介面下載sdk,解壓進入

android開發SharedPreferences儲存物件

因為作者最近在做一個收藏的功能,涉及到了資料的儲存和讀取,又因為太懶,不想去使用ContentProvider,所以種種原因讓我選擇了使用SharedPreferences來儲存資料,但是儲存一條、兩條單獨的資料是可以的,但是要儲存物件!作者只能說咋搞!怕啥,一步一步的來嘛

Android開發利用ConditionVariable同步執行緒結果

概述 在我們日常開發當中有時會遇到這樣的場景,例如一個操作依賴2個數據,而這2個數據是通過2個執行緒分別計算得到的,而這個2個計算結果完成的先後順序是不能事先確定的,那我們就得想辦法同步這2個執行緒的結果。 解決方案 方案1 使用在各個工作執行緒都

Android開發狀態選擇器(selector)詳解

這些天博主的專案進度比較快,現在伺服器那端進度較慢,所以博主晚上最近會比較有時間,所以最近會多寫些部落格出來和大家分享~希望能夠幫助到大家。 所謂狀態選擇器,就是控制元件(view或者viewgroup)的狀態發現變化的時候,我們可以再指定的狀態下,切換控制元件的背景屬性(

Android開發ViewPager+ActionBar+Fragment實現響應式可滑動Tab

                  按照一般的思路,我們或許會這麼做:首先,使用getActionBar()方法獲得操作欄,然後我們將操作欄的導航模式設定為Tab,並新增一些Tab,然後實現TabListener介面;其次,我們將多個佈局通過Inflater()方法變成View,然後

Android開發getX,getRawX,getWidth,getTranslationX等的區別

save string hlist getwidth sta 是我 touch 項目 寬度 轉載請註明出處:http://blog.csdn.net/dmk877/article/details/51550031 好久沒寫博客了,最近工作確實挺忙的,剛剛結束了一個

Android 開發Windows環境下Android Studio安裝和使用教程(圖文詳細步驟)

9.png 虛擬機 jdk版本 編寫 clip 開發平臺 集成開發 arc 電腦安裝 鑒於谷歌最新推出的Android Studio備受開發者的推崇,所以也跟著體驗一下。 一、介紹Android Studio Android Studio 是一個Android

Android資源圖像資源(狀態圖像資源)

one android資源 nco 文件夾 nts 淡出 else if fontsize bsp 在上一篇博文中。我主要解說了XML圖像資源中的圖層資源,在此圖像資源博文中我會給大家陸續解說XMl圖像資源的圖像狀態資源、圖像級別資源、淡入淡出資源、嵌入圖像資源、剪切圖

Android開發AudioManager(音頻管理器)具體解釋

應該 數量 service eth out 開發 要求 type 路由 AudioManager簡單介紹: AudioManager類提供了訪問音量和振鈴器mode控制。使用Context.getSystemService(Context.AUDIO_SERVICE)

【入門篇】ANDROID開發BUG專講

world 自然 執行 類型 效率 str 積累 全部 href 話說諸葛亮是一個優秀的程序員,每個錦囊都是應對不同的case而編寫的。可是優秀的程序員也敵只是更優秀的bug。六出祈山。七進中原,鞠躬盡瘁,死而後已的諸葛亮僅僅由於有一