Fragment的数据保存与恢复

前言:

嗨!各位老铁,好久不见。最近工作有点忙,事情比较多,更新可能有点慢了哦。之前的Android回顾系列已经完结了。有兴趣的可以去看看和点赞。

需求:

最近工作上有业务需求,需要从Fragment A 跳转到Fragment B之后,退回到Fragment A,要恢复跳转之前的数据和View。所以,今天要给大家说一下的是Fragment的数据恢复与保存

Android中数据的保存与恢复

首先提到数据恢复,首先想到的应该是Activity的数据恢复与保存。大家想的都是在onSaveInstanceState方法进行保存。但是,我们今天讲的Fragment的数据恢复与保存,需要手动的调用保存方法进行保存,避免保存失败。

下面是具体的实现步骤:
  1. 首先我们需要了解一下setArguments()和getArguments()方法的作用

在Fragment中,我们需要使用setArguments(bundle)来传递bundle数据。getArguments()方法获取数据。

    /**
     * 在初始化这个Fragment实例的时候,就需要传递这个bundle数据进去。注意:在调用显示这个Fragment之前就要设置这个函数。
     * @return
     */
    @NonNull
    public static NewsFragment newInstance() {
        if (audioFragment==null){  //采用double Check的方式创建单例
            synchronized (NewsFragment.class){
                if (audioFragment==null){
                    audioFragment = new NewsFragment();
                }
            }
        }
        Bundle bundle = new Bundle();
        audioFragment.setArguments(bundle);
        return audioFragment;
    }
  1. 然后我们就要正式的进行临时数据的获取了。
  • 在OnActivityCreated()生命周期方法中判断是否有保存临时数据
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.i(TAG, "isVoce " + isVoiceLaunch());
        if (!reStoreStateFromArguments()) {  //判断是否有保存过临时数据
            Log.i(TAG, "onActivityCreated:");
        }
    }

在OnActivityCreated中进行判断是因为回退的时候,Fragment会重走这个生命周期

    public boolean reStoreStateFromArguments() {
        Bundle bundle = getArguments();  //第一步、拿到之前保存的bundle数据
        saveState = bundle.getBundle("savedViewState");//第二步、通过bundle获取之前保存时候设置的数据bundle
        Log.i(TAG, "sacve " + saveState);
        if (saveState != null) {  //判断是是否有保存过数据 
            Log.i(TAG, "恢复数据");
            reStoreState();
            return true;
        }
        return false;
    }

在reStoreState()方法里面取出之前存储的数据并绑定到对应的View上面

    public void reStoreState() {
        int saveCurrentProgress = saveState.getInt("currentProgress", 0);
        int saveDuration = saveState.getInt("duration", 0);
        String audio_album = saveState.getString("audio_album", null);
        String title = saveState.getString("title", null);
        Glide.with(MateApplication.getInstance()).load(audio_album).error(R.mipmap.play_rdi_album_music).into(play_rdi_album);
        setFragmentTitle(title);
        audioSeek.setProgress(saveCurrentProgress);
        audioSeek.setMax(saveDuration);
        //获取到当前播放的时间
        String time = UIUtil.formatTime(saveCurrentProgress);
        audioCurrentProgress.setText(time);
        String formatTime = UIUtil.formatTime(saveDuration);
        audioDuration.setText(formatTime);
        if (isPlaying) {
            play();
        }
        Log.i(TAG, "生命周期 isPlaying " + AppConstants.isPlaying);
    }
  1. 最后,我们在Fragment的onSaveInstanceState和onDestroyView()方法中手动的去调用保存数据的方法。
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        saveStateToArguments();
    }
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.i(TAG, "onDestroyView: ");
        saveStateToArguments();
    }

在onDestroyView中手动调用,是为了防止有时候onSaveInstanceState()方法在Fragment销毁的时候不被调用。

    public void saveStateToArguments() {
        Log.i(TAG, "保存数据");
        saveState = saveState();//保存数据
        if (saveState != null) {
            Bundle bundle = getArguments(); // 获取之前初始化时候的bundle
            bundle.putBundle("savedViewState", saveState);//将bundle传入数据
        }
    }

将需要保存的数据,封装到bundle中进行传递

    public Bundle saveState() {
        Bundle outState = new Bundle();
        if (dbdataBeanList != null && dbdataBeanList.size() > 0 && dbdataBeanList.get(getCurrent()) != null) {
            DataBean.DbdataBean audioBean = dbdataBeanList.get(getCurrent());
            outState.putString("title", audioBean.getTrack());
            outState.putString("audio_album", audioBean.getCover_url_large());
            outState.putInt("currentProgress", currentProgress);
            outState.putInt("duration", duration);
            Log.i(TAG, "保存数据");
        }
        return outState;
    }

End

  关于Android中临时数据的保存与恢复,平时在业务中遇见的场景还是挺多的,我们需要好好的理解一下。欢迎大家点赞和指正哦。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容