Android之Fragment 跳转返回重复加载重复执行onCreateView的四种解决方法

news/2024/11/18 0:14:53/

前言: 

Fragment 跳转返回重复加载重复执行 onCreateView 的问题通常是因为 Fragment 生命周期方法的调用顺序和使用不当所导致的。

1,onSaveInstanceState()方法

一种解决方法是在 Fragment 中使用 onSaveInstanceState() 方法保存 Fragment 的状态,并在 onCreate() 方法中进行状态恢复,避免重复执行 onCreateView()。具体步骤如下:

  1. 在 Fragment 中重写 onSaveInstanceState(Bundle outState) 方法,将状态信息保存到 Bundle 对象中。
  2. 在 Fragment 的 onCreate() 方法中检查 savedInstanceState 对象是否为 null,如果不是,则从 savedInstanceState 中恢复状态信息。
  3. 在 onCreateView() 方法中判断是否已存在 UI 视图,如果已经存在则不需要重新创建,直接返回缓存的视图即可。

示例代码如下:

public class MyFragment extends Fragment {private View rootView;private boolean isViewCreated = false;private boolean isDataLoaded = false;@Overridepublic void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putBoolean("isDataLoaded", isDataLoaded);}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (savedInstanceState != null) {isDataLoaded = savedInstanceState.getBoolean("isDataLoaded");}}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {if (rootView == null) {rootView = inflater.inflate(R.layout.fragment_my, container, false);isViewCreated = true;} else {isViewCreated = false;ViewGroup parent = (ViewGroup) rootView.getParent();if (parent != null) {parent.removeView(rootView);}}if (!isDataLoaded) {loadData();}return rootView;}private void loadData() {// 加载数据的操作isDataLoaded = true;}
}

2,使用Fragment 的 replace() 方法进行跳转,而不是使用 add() 方法

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, new MyFragment());
transaction.addToBackStack(null);
transaction.commit();

3,使用标识:hasInitialized

在Fragment的onCreateView中进行数据的初始化和界面的更新等操作时,需要先判断之前是否已经进行过相关操作,如果已经操作过则不需要再次执行,可以通过增加标记变量来实现。

public class MyFragment extends Fragment {private boolean hasInitialized = false;private TextView mTextView;private View mView;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {if (!hasInitialized) {mView = inflater.inflate(R.layout.fragment_my, container, false);mTextView = (TextView) mView.findViewById(R.id.tv_content);initData();hasInitialized = true;}return mView;}private void initData() {// 如果之前没有初始化过数据,则初始化并显示// 如果已经初始化过了,则不需要再次初始化if (TextUtils.isEmpty(mTextView.getText())) {mTextView.setText("这是我的Fragment");}}
}

4,rootview是否已存在判断,此方法跟第三种第一种有一点儿相似之处。

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  if (null != view) {  ViewGroup parent = (ViewGroup) view.getParent();  if (null != parent) {  parent.removeView(view);  }  } else {  view = inflater.inflate(R.layout.fragment_main, container, false);  initView(view);// 控件初始化  }  return view;  } 

总结:

个人感觉最简单的解决方法是3,4 ,具体选用哪个方法需根据实际情况来定。

注意:只适用于返回键重新回退的判断处理,切记,多次重复打开的界面貌似无效


http://www.ppmy.cn/news/83945.html

相关文章

【python】制作一个点单小程序!

周末总是在吃的方面,及其纠结,今天来制作一个点单小程序,加入自己喜欢吃的东西,来慢慢挑选,让每个周末快乐无限! 一.安装环境 python 3.7.8 QT xlrd、xlwt库使用pip接口进行安装 pip install xlrd pip …

智能工厂已成为制造业数字化转型的重心

我国“十四五”规划纲要提出,要深入实施智能制造和绿色制造工程,发展服务型制造新模式,推动制造业高端化智能化绿色化。随着5G等新一代信息技术与制造业不断深度融合,制造业的智能化发展成为未来我国制造业转型升级的重要方向。《…

freertos任务优先级分配

RQ 任务:IRQ 任务是指通过中断服务程序进行触发的任务,此类任务应该设置为所有任务里面优先 级最高的。高优先级后台任务:比如按键检测,触摸检测,USB 消息处理,串口消息处理等,都可以归为这一类…

Springboot +spring security,配置多个数据源:验证不同用户表

一.简介 上篇文章写到,我们在配置jdbc和mybatis 来源,进行登录后,出现了如下错误! 后面解决方案是:屏蔽了其中一个来源,登陆成功,也分析了其原因。 但是,但是如果需要配置多个数据来源&#…

Linux——网络套接字1|socket编程

IP地址(公网IP),标定了主机的唯一性。 通常情况,把数据送到对方的机器是目的吗? 不是的,真正的网络通信过程其实是进程间通信,如客户端进程和服务器进程,我们把数据在主机间转发仅仅是手段,机器收到数据之后,需要将数据交付给指定的进程,当客户端有多个进程在运行时…

优化 docker 容器性能慢问题

问题: 部署环境下tomcat容器启动缓慢,耗时10多分钟,性能较差,同时后端服务响应较慢。 排查: 宿主环境: docker使用情况: 对比结果CPU、内存使用率都不高。 针对docker环境进行检查&#xff…

Three.js--》实现3d圣诞贺卡展示模型

目录 项目搭建 初始化three.js基础代码 加载环境模型 设置环境纹理 添加水面并设置阴影效果 实现幽灵小球的运动 实现相机切换和文字切屏 实现漫天星星和爱心样式 今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目…

Vue简单的引入主流地图

百度地图 引入ak 在 public/index.html 中引入,根据官网教程&#xff0c;注册百度地图&#xff0c;获取应用ak。 页面代码 <template><div class"pos-monitor"><div id"map" style"height:120vh; width:100%"></div>…