首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在viewpager中保存和恢复片段状态

基础概念

ViewPager 是 Android 中用于实现滑动页面切换的控件,通常与 Fragment 结合使用。每个页面通常对应一个 Fragment。为了在配置更改(如屏幕旋转)或应用进程被杀死并重新启动时保持 Fragment 的状态,需要保存和恢复这些状态。

相关优势

  1. 用户体验:保持用户当前浏览的位置和状态,避免因配置更改导致的重复操作。
  2. 数据一致性:确保用户在应用重启后看到的数据与离开时一致。

类型

  • 临时状态:如用户输入的数据。
  • 持久状态:如 Fragment 的布局状态。

应用场景

  • 新闻阅读应用:用户在浏览新闻时,屏幕旋转后应继续显示当前新闻。
  • 表单填写应用:用户在填写表单时,应用重启后应恢复之前的填写内容。

保存和恢复片段状态的方法

保存状态

Android 系统会在配置更改时自动保存 Fragment 的状态,但有时需要手动干预以确保状态的正确保存。

代码语言:txt
复制
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    // 手动保存需要的状态
    outState.putString("key", "value");
}

恢复状态

FragmentonCreateonViewCreated 方法中恢复状态。

代码语言:txt
复制
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        String value = savedInstanceState.getString("key");
        // 恢复状态
    }
}

遇到问题及解决方法

问题:状态未正确恢复

原因

  1. 可能在 Fragment 的生命周期方法中未正确处理状态保存和恢复。
  2. ViewPager 的适配器可能未正确管理 Fragment 的实例。

解决方法

确保在 FragmentonSaveInstanceStateonCreate 方法中正确处理状态的保存和恢复。

代码语言:txt
复制
public class MyFragment extends Fragment {
    private String savedValue;

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("key", savedValue);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            savedValue = savedInstanceState.getString("key");
        }
    }
}

对于 ViewPager 的适配器,确保使用 FragmentStatePagerAdapterFragmentStateAdapter(适用于 AndroidX),它们会在 Fragment 不可见时销毁其视图,但保留其状态。

代码语言:txt
复制
public class MyPagerAdapter extends FragmentStatePagerAdapter {
    public MyPagerAdapter(@NonNull FragmentManager fm, int behavior) {
        super(fm, behavior);
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return new MyFragment();
    }

    @Override
    public int getCount() {
        return NUM_PAGES;
    }
}

示例代码

代码语言:txt
复制
public class MainActivity extends AppCompatActivity {
    private ViewPager viewPager;
    private MyPagerAdapter pagerAdapter;

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

        viewPager = findViewById(R.id.viewPager);
        pagerAdapter = new MyPagerAdapter(getSupportFragmentManager(), FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
        viewPager.setAdapter(pagerAdapter);
    }
}

通过以上方法,可以有效保存和恢复 ViewPagerFragment 的状态,提升用户体验和应用稳定性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

ViewPager中Fragment状态保存的哪些事

的状态信息,并且以下标的方式进行了保存,当我们在滑动 ViewPager 时,其会加载并初始化指定 position 所对应 Fragment ,并将缓存的 Fragment 的状态信息 set 进去...Fragment部分 通过上面的方式,我们可以简单的知道 ViewPager 是如何帮我们进行状态还原与保存,那 Fragment 到底是在什么时候去使用这个状态呢?...在Fragment中我们去看这个方法:onViewStateRestored() 官方解释,此方法被调用时意味着 Fragment所有状态 都已经还原。...key 存到了一个list集合中,然后在调用 getItem() 初始化Fragment时,其会将之前保存的状态重新 set 给我们的 Fragment 实例。...知道了这个概念,我们也就可以自己做一些小扩展,比如我们可以在部分情况下主动将我们的Fragment状态保存起来,以便在后面进行恢复,也即就是使用以下两个方法即可。

1.4K20

JAVA设计模式22:备忘录模式,用于保存和恢复对象的状态

一、什么是备忘录模式 备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不暴露对象内部状态的情况下保存和恢复对象的状态。...需要保存和恢复对象的状态,但又不希望暴露对象内部状态给其他对象。 备忘录模式提供了一种在不破坏封装性的前提下保存和恢复对象状态的方式,使得对象可以在需要时回滚到之前的某个状态。...通过保存对象的不同状态到备忘录中,可以记录对象的历史状态,并在需要时进行查看和回溯。 编辑器或文档恢复:备忘录模式在编辑器或文档编辑器中可以用于实现恢复功能。...通过保存对象的状态到备忘录中,在事务执行失败时可以将对象恢复到之前的状态,保证事务的一致性和完整性。...总之,备忘录模式适用于需要保存和恢复对象状态的场景,尤其是在需要实现撤销操作、历史记录、恢复功能等方面,它可以有效地解决状态管理和历史记录的问题,并提供更好的灵活性和可维护性。

44230
  • 【Ruby on Rails】Model中关于保存之前的原值和修改状态

    今天在Rails的Model中遇到了一个问题—— 当我从Model类中获取了一个ActiveRecord对象,对其进行了一系列修改(尚未保存),我该如何确定究竟哪些修改了呢?...(设Model为Option,相关的的参数为correct) 我本来采取的方法是——在数据表中新增一个ori_correct参数,每次对象保存之前都和correct做到同步,这样一来,是不是correct...# => true/false 也就是在相应字段后面添加_changed?,这样一来问题直接解决,亲测有效。 然而很快另外一个问题又来了,既然知道了是否被改变,那该如何知道原来的值是什么呢?...同样的,我在StackOverFlow上找到了解决办法 Appending _was to your attribute will give you the previous value....(关于更多的关于ActiveModel::Dirty所支持的各种神奇功能,请在http://api.rubyonrails.org/中输入ActiveModel::Dirty)

    1.7K90

    在Oracle中,实例恢复和介质恢复的区别是什么?

    Q 题目 在Oracle中,实例恢复和介质恢复的区别是什么? A 答案 Redo日志是Oracle为确保已经提交的事务不会丢失而建立的一种机制。...恢复就是使用归档日志文件和联机Redo日志文件将不一致的数据库应用到一致性状态。...检查点位置始终保证所有比其SCN低的检查点所对应的已提交更改都已保存到数据文件。 在实例恢复期间,数据库必须应用检查点位置和重做线程结尾之间发生的更改。如上图所示,某些更改可能已经写入数据文件。...但是,这些数据文件可能还包含未提交的更改,要么是在实例失败前保存到数据文件中的,或者是在前滚过程中引入的。...Oracle数据库使用检查点位置,保证每个低于其SCN的已提交更改都已保存到磁盘。Oracle数据库应用Undo块,以回滚数据块中在实例失败前写入的或前滚过程中引入的未提交更改。

    1.9K20

    Android入门教程 | Fragment 基础概念

    不过,当 Activity 正在运行(处于已恢复生命周期状态)时,可以独立操纵每个片段,如添加或移除片段。...savedInstanceState 参数是在恢复片段时,提供上一片段实例相关数据的 Bundle(处理片段生命周期部分对恢复状态做了详细阐述)。...处理Fragment生命周期 管理片段生命周期与管理 Activity 生命周期很相似。和 Activity 一样,片段也以三种状态存在: 已恢复:片段在运行中的 Activity 中可见。...宿主 Activity 已停止,或片段已从 Activity 中移除,但已添加到返回栈。已停止的片段仍处于活动状态(系统会保留所有状态和成员信息)。...如要了解保留界面状态的更多信息,请参阅保存界面状态。 对于 Activity 生命周期与片段生命周期而言,二者最显著的差异是在其各自返回栈中的存储方式。

    3.5K40

    【DB笔试面试428】在Oracle中,实例恢复和介质恢复的区别是什么?

    题目 在Oracle中,实例恢复和介质恢复的区别是什么? 答案 Redo日志是Oracle为确保已经提交的事务不会丢失而建立的一种机制。...恢复就是使用归档日志文件和联机Redo日志文件将不一致的数据库应用到一致性状态。...检查点位置始终保证所有比其SCN低的检查点所对应的已提交更改都已保存到数据文件。 ? 在实例恢复期间,数据库必须应用检查点位置和重做线程结尾之间发生的更改。如上图所示,某些更改可能已经写入数据文件。...但是,这些数据文件可能还包含未提交的更改,要么是在实例失败前保存到数据文件中的,或者是在前滚过程中引入的。...Oracle数据库使用检查点位置,保证每个低于其SCN的已提交更改都已保存到磁盘。Oracle数据库应用Undo块,以回滚数据块中在实例失败前写入的或前滚过程中引入的未提交更改。

    1.5K21

    Android后台杀死系列之一:FragmentActivity及PhoneWindow后台杀死处理机制

    为什么出现两个DialogFragment Fragment在被创建之后,如果不通过add或者replace添加到Activity的布局中是不会显示的,在保存现场的时候,也是保存了add的这个状态的,来看一下...显示,再stop A,在stop A的时候,需要保存A的现场,因为不可见的Activity都是可能被后台杀死的,比如,在开发者选项中打开不保留活动,就会达到这种效果,在启动另一个Activity时,上一个...,比如:当前获取焦点的View的id、ActionBar、View的一些状态,当然saveHierarchyState递归遍历所有子View,保存所有需要保存的状态: ViewGroup.java...后台杀死时View的保存及恢复 FragmentTabHost应对后台杀死做的兼容 FragmentTabHost其实跟ViewPager很相似,在onSaveInstanceState执行的时候保存当前位置...针对Window,如果不想让View使用恢复逻辑,在基类的FragmentActivity中覆盖onRestoreInstanceState函数即可。

    3.1K30

    Android开发笔记(六十七)嵌入页面的碎片

    Fragment 概念 Android从3.0之后引入了Fragment,可以把它理解为页面的一个片段,比如一个html网页就包含一个header头部片段,以及一个body身体片段。...设计Fragment的目的是让页面布局更加灵活,不但可以随意组装和拼接各个片段,还可以只更新某个片段实现页面局部更新的功能(这个类似网页的ajax技术)。...Fragment可以协助我们完成如下任务: 1、在一个页面中嵌入多个连续可翻页的子视图,方面使用ViewPager统一管理; 2、开发一些通用的小部件,内部封装好代码逻辑,可直接嵌入到任意页面。...若想给Fragment传递参数,可在Fragment类中定义一个静态方法newInstance,在该方法中通过setArguments函数写入Bundle对象;然后重写方法onCreateView,在该方法中通过...方法,因为此时可能状态尚未恢复; 2、不要往Fragment传递较大的参数,比如说图像数据; 3、不要在异步任务中调用commit方法; 竖屏与横屏切换的开发注意事项如下,手机与平板的切换可参照处理

    1.3K60

    TabLayout+ViewPager+Fragment实现切页展示「建议收藏」

    : 创建存储多个Fragment实例的列表 创建PagerAdapter实例并关联到Viewpager中 将ViewPager关联到Tablayout中 根据需求改写Tablayout属性* 最后一步不是必须的...指的是所包含存储的Fragment对象的状态是否保存。...本小节最后,告诉大家一个关于如何选择PagerAdapter的结论: FragmentPagerAdapter适用于Fragment比较少的情况,它会把每一个Fragment保存在内存中,不用每次切换的时候...,去保存现场,切换回来在重新创建,所以用户体验比较好。...这也是FragmentStatePagerAdapter的精髓之处,如果注释掉,一旦Activity被回收进入异常销毁状态,Fragment就无法恢复之前的状态,因此这种方法也是有纰漏和局限性的。

    3.3K10

    Android高频面试专题 - 基础篇(二)Fragment

    主要是支持在大屏幕上动态和更为灵活的去组合或是交换UI组件,通过将Activity的布局分割成若干个Fragment,可以在运行时编辑Activity的呈现,并且那些变化会被保存在由Activity管理的后台栈里面...正确的应该是直接使用 startActivityForResult()方法 requestCode 请勿传-1 7、数据保存和恢复 和Activity类似,Fragment也有onSaveInstanceState...的方法,在此方法中进行保存数据,然后在onCreate或者onCreateView或者onActivityCreated进行恢复都可以。...,和remove()不同,此时fragment的状态依然由FragmentManager维护 attach() 重建view视图,附加到UI上并显示 ransatcion.commit() 提交事务 10...onResume(), 所有ViewPager中的Fragment都会执行onResume(),所以在很容易造成网络丢包或者网络堵塞等问题,所以Fragment使用懒加载机制,只有当Fragment真正对用户可见时

    1.4K10

    Android技能树 — Fragment总体小结

    然后网上有很多教程,叫你提交的时候使用commitAllowingStateLoss()方法,虽然说不会抛出错误,但是如果在Activity已经保存状态完之后提交了它,到时候Ativity意外崩溃,再恢复数据的时候就不会恢复在...Activity保存状态之后提交的fragment的更新,造成状态丢失了。...所以我们比如一些对象可以保持在fragment中,这时候Activity重新恢复后,其他对象可以从fragment中找回。...Fragment重建恢复数据 推荐下面这篇文章: [译] 保存/恢复 Activity 和 Fragment 状态的最佳实践 引用一段话: 完全分开处理Fragment状态和view状态 为了使你的代码变得干净和可扩展...如果这里有任何属性是属于View的,在View内部进行保存和恢复.如果这里有任何属性是属于Fragment的,在Fragment内部进行保存和恢复。

    35010

    Android技能树 — Fragment总体小结

    然后网上有很多教程,叫你提交的时候使用commitAllowingStateLoss()方法,虽然说不会抛出错误,但是如果在Activity已经保存状态完之后提交了它,到时候Ativity意外崩溃,再恢复数据的时候就不会恢复在...Activity保存状态之后提交的fragment的更新,造成状态丢失了。...所以我们比如一些对象可以保持在fragment中,这时候Activity重新恢复后,其他对象可以从fragment中找回。...推荐下面这篇文章: [译] 保存/恢复 Activity 和 Fragment 状态的最佳实践 引用一段话: 完全分开处理Fragment状态和view状态 为了使你的代码变得干净和可扩展,你最好把Fragment...如果这里有任何属性是属于View的,在View内部进行保存和恢复.如果这里有任何属性是属于Fragment的,在Fragment内部进行保存和恢复。

    1.1K20

    仿微信PhotoView+Viewpager浏览视频,图片,切换下一页前一页恢复原本大小

    之前效果 完成效果: 仿微信PhotoView+Viewpager浏览视频,图片,切换下一页前一页恢复原本大小 使用PhotoView+Viewpager浏览图片时,默认情况下上一张图片的状态是不会恢复的...,了解的朋友肯定知道是Viewpager的缓存问题,要解决的话重写Viewpager修改缓存数,这样当然可以,但是效果的话,并不是很好,滑动的时候下一页处于黑屏状态,这次给大家分享一个方法,如果有更好的或者意见...,欢迎在评论指出 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override...//获取当前页面的view View child=mViewPager.getChildAt(i); //获取当前页面中的...(); //通过photoViewAttacher设置缩放大小 //第一个参数是获取photoViewAttacher自带的缩放大小最小值,第二个和第三个参数设置缩放中心

    44910

    FragmentPagerAdapter 滑动过后界面不显示的解决方案

    最近工作中UI给出如图设计,心想这个结合viewpager,fragment,FragmentPagerAdapter就能构建出来. ?...立马在getItem代码中打断点,发现左右滑动时压根就没有调用getItem方法....实际运行时,滑动时会直接去内存中寻找.这样问题就可以断定为fragment再次添加到界面时数据丢失了,没有保存下来.这样就好办了,我们在frament中做数据保存处理即可.在fragment中加入类似代码...} 心想这下,该没有事了吧.代码一跑,滑动几次后妥妥还是白屏无数据.一怒之下再次 google fragment 的数据恢复和保存处理.果然已有现成的解决方案.在此感谢泡在网上的日子的解决方案...结论:FragmentPagerAdapter和viewpager滑动白屏无数据,是由于恢复内存中的fragment的数据丢失,需要自己做手动数据保存,这样才能避免此情况的出现.

    1.2K30

    在MySQL中,如何进行备份和恢复数据库?物理备份和逻辑备份的区别是什么?

    物理备份的优点是备份速度快,恢复速度也较快。但缺点是备份文件较大,不易跨平台,且只能在相同架构的MySQL服务器上恢复。...二、逻辑备份 逻辑备份是将数据库中的数据和结构导出为SQL语句的形式,以文本文件的形式存储备份数据。...backup_file.sql 还原数据库:mysql -u username -p database_name < backup_file.sql 使用MySQL Workbench等图形界面工具进行备份和恢复...缺点是备份和恢复速度较慢。 结论 物理备份和逻辑备份的主要区别在于备份文件的形式和备份恢复的灵活性。...物理备份直接复制数据库的二进制文件,备份文件较大,恢复时只能在相同架构的MySQL服务器上使用;逻辑备份将数据库导出为SQL语句的形式,备份文件较小,恢复时可跨平台使用,也可以进行数据的修改和筛选。

    74381

    【DB笔试面试785】在Oracle中,RMAN中关于备份或归档文件状态OBSOLETE和EXPIRED的区别是什么?

    ♣ 题目部分 在Oracle中,RMAN中关于备份或归档文件状态OBSOLETE和EXPIRED的区别是什么? ♣ 答案部分 OBSOLETE:是指根据保留策略来确定该备份是否在恢复的时候需要。...EXPIRED:是指执行CROSSCHECK时,根据恢复目录或控制文件中记录的备份信息来定位备份集或镜像副本,若找不到对应的文件,则这些文件的状态被置为EXPIRED。...如果在备份过程中,归档文件被手动通过rm命令删除,那么会报错:RMAN-06059。...解决办法就是在RMAN中校验归档文件后再删除失效的归档文件,如下所示: CROSSCHECK ARCHIVELOG ALL; LIST EXPIRED ARCHIVELOG ALL; DELETE EXPIRED...QQ:646634621 QQ群:230161599、618766405 ● 微信:lhrbestxh ● 微信公众号:DB宝 ● 提供Oracle OCP、OCM、高可用(rac+dg+ogg)和MySQL

    1.2K10
    领券