我已经看到了两种在应用程序中实例化新Fragment的常规做法:

Fragment newFragment = new MyFragment();

Fragment newFragment = MyFragment.newInstance();

第二个选项使用静态方法newInstance()并且通常包含以下方法。

public static Fragment newInstance()
{MyFragment myFragment = new MyFragment();return myFragment;
}

最初,我认为主要的好处是可以在创建Fragment的新实例时重载newInstance()方法以提供灵活性-但我也可以通过为Fragment创建重载的构造函数来做到这一点。

我错过了什么?

一种方法比另一种方法有什么好处? 还是只是好的做法?


#1楼

还有另一种方法:

Fragment.instantiate(context, MyFragment.class.getName(), myBundle)

#2楼

不同意 yydi的回答 :

如果Android决定稍后再创建片段,它将调用片段的无参数构造函数。 因此,重载构造函数不是解决方案。

我认为这是一个解决方案,也是一个很好的解决方案,这正是Java核心语言开发它的原因。

的确,Android系统可以销毁并重新创建您的Fragment 。 因此,您可以执行以下操作:

public MyFragment() {
//  An empty constructor for Android System to use, otherwise exception may occur.
}public MyFragment(int someInt) {Bundle args = new Bundle();args.putInt("someInt", someInt);setArguments(args);
}

即使Fragment是由系统重新创建的,它也允许您someIntgetArguments()获取getArguments() 。 这是比static构造函数更好的解决方案。

我认为static构造函数是无用的,不应使用。 如果将来您想扩展此Fragment并向构造函数添加更多功能,它们也会限制您。 使用static构造函数,您将无法执行此操作。

更新:

Android添加了检查,将所有非默认构造函数标记为错误。
由于上述原因,我建议禁用它。


#3楼

我相信我对此有一个非常简单的解决方案。

public class MyFragment extends Fragment{private String mTitle;private List<MyObject> mObjects;public static MyFragment newInstance(String title, List<MyObject> objects)MyFragment myFrag = new MyFragment();myFrag.mTitle = title;myFrag.mObjects = objects;return myFrag;}

#4楼

由于存在有关最佳实践的问题,我想补充一点,在使用某些REST Web服务时,通常最好使用混合方法来创建片段。

对于显示用户片段的情况,我们不能传递复杂的对象,例如某些用户模型

但是我们可以做的是检入onCreate该用户!= null,如果没有,则从数据层将其带入,否则使用现有的。

这样一来,我们既获得了通过Android重新创建片段的情况下通过userId进行重新创建的能力,又获得了对用户操作的敏锐度,以及通过持有对象本身或仅保留其ID来创建片段的能力

像这样:

public class UserFragment extends Fragment {public final static String USER_ID="user_id";private User user;private long userId;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);userId = getArguments().getLong(USER_ID);if(user==null){//// Recreating here user from user id(i.e requesting from your data model,// which could be services, direct request to rest, or data layer sitting// on application model//user = bringUser();}}public static UserFragment newInstance(User user, long user_id){UserFragment userFragment = new UserFragment();Bundle args = new Bundle();args.putLong(USER_ID,user_id);if(user!=null){userFragment.user=user;}userFragment.setArguments(args);return userFragment;}public static UserFragment newInstance(long user_id){return newInstance(null,user_id);}public static UserFragment newInstance(User user){return newInstance(user,user.id);}
}

#5楼

尽管@yydl给出了为什么newInstance方法更好的令人信服的理由:

如果Android决定稍后再创建片段,它将调用片段的无参数构造函数。 因此,重载构造函数不是解决方案。

仍然有可能使用构造函数 。 要了解原因,首先我们需要了解Android为什么使用上述解决方法。

在使用片段之前,需要一个实例。 Android调用YourFragment()无参数构造函数)来构造片段的实例。 在这里,您编写的所有重载构造函数都将被忽略,因为Android无法确定要使用哪个构造函数。

在Activity的生存期内,片段会按上述方式创建并被Android多次破坏。 这意味着,如果将数据放在片段对象本身中,则一旦片段被破坏,数据将丢失。

要解决此问题,android会要求您使用Bundle (调用setArguments() )存储数据,然后可以从YourFragment访问该YourFragment 。 参数bundle受Android保护,因此可以保证是持久的

设置此捆绑包的一种方法是使用静态newInstance方法:

public static YourFragment newInstance (int data) {YourFragment yf = new YourFragment()/* See this code gets executed immediately on your object construction */Bundle args = new Bundle();args.putInt("data", data);yf.setArguments(args);return yf;
}

但是,构造函数:

public YourFragment(int data) {Bundle args = new Bundle();args.putInt("data", data);setArguments(args);
}

可以做与newInstance方法完全相同的事情。

自然,这将失败,并且是Android希望您使用newInstance方法的原因之一:

public YourFragment(int data) {this.data = data; // Don't do this
}

作为进一步的说明,这是Android的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;
}

请注意,Android要求在构造时设置参数,并保证将保留这些参数。

编辑 :正如@JHH的注释中指出的那样,如果要提供需要一些参数的自定义构造函数,则Java将不会为您的片段提供无arg默认构造函数。 因此,这将需要您定义一个no arg构造函数,这是可以使用newInstance factory方法避免的代码。

编辑 :Android不允许再使用重载的构造函数来存储片段。 您必须使用newInstance方法。


#6楼

实例化片段的最佳方法是使用默认的Fragment.instantiate方法或创建工厂方法来实例化片段
注意:始终在片段中创建一个空的构造函数,而还原片段存储器将抛出运行时异常。


#7楼

在Android中使用参数实例化片段的最佳做法是在片段中使用静态工厂方法。

public static MyFragment newInstance(String name, int age) {Bundle bundle = new Bundle();bundle.putString("name", name);bundle.putInt("age", age);MyFragment fragment = new MyFragment();fragment.setArguments(bundle);return fragment;
}

您应该避免使用片段实例设置字段。 因为每当android系统重新创建您的片段时,如果感觉到系统需要更多的内存,它将比不使用不带参数的构造函数来重新创建您的片段。

您可以在此处找到有关最佳实践的更多信息, 以实例化带有参数的片段 。


#8楼

setArguments()没有用。 只会带来一团糟。

public class MyFragment extends Fragment {public String mTitle;public String mInitialTitle;public static MyFragment newInstance(String param1) {MyFragment f = new MyFragment();f.mInitialTitle = param1;f.mTitle = param1;return f;}@Overridepublic void onSaveInstanceState(Bundle state) {state.putString("mInitialTitle", mInitialTitle);state.putString("mTitle", mTitle);super.onSaveInstanceState(state);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {if (state != null) {mInitialTitle = state.getString("mInitialTitle");mTitle = state.getString("mTitle");} ...}
}

#9楼

一些kotlin代码:

companion object {fun newInstance(first: String, second: String) : SampleFragment {return SampleFragment().apply {arguments = Bundle().apply {putString("firstString", first)putString("secondString", second)}}}
}

您可以通过以下方式获取参数:

val first: String by lazy { arguments?.getString("firstString") ?: "default"}
val second: String by lazy { arguments?.getString("secondString") ?: "default"}

#10楼

使用此代码100%修复您的问题

firstFragment中输入此代码

public static yourNameParentFragment newInstance() {Bundle args = new Bundle();args.putBoolean("yourKey",yourValue);YourFragment fragment = new YourFragment();fragment.setArguments(args);return fragment;
}

此样本发送布尔数据

和在SecendFragment

yourNameParentFragment name =yourNameParentFragment.newInstance();Bundle bundle;bundle=sellDiamondFragments2.getArguments();boolean a= bundle.getBoolean("yourKey");

第一个片段中的必须值是静态的

快乐的代码


#11楼

如果Android决定稍后再创建片段,它将调用片段的无参数构造函数。 因此,重载构造函数不是解决方案。

话虽如此,将内容传递给Fragment以便在Android重新创建Fragment后可用的方法是将包传递给setArguments方法。

因此,例如,如果我们想将整数传递给片段,我们将使用类似以下内容:

public static MyFragment newInstance(int someInt) {MyFragment myFragment = new MyFragment();Bundle args = new Bundle();args.putInt("someInt", someInt);myFragment.setArguments(args);return myFragment;
}

然后在Fragment onCreate()您可以使用以下方式访问该整数:

getArguments().getInt("someInt", 0);

即使Fragment是由Android重新创建的,此Bundle仍然可用。

另请注意:只能在将Fragment附加到Activity之前调用setArguments

android开发人员参考中也记录了这种方法: https : //developer.android.com/reference/android/app/Fragment.html


#12楼

我看到的使用newInstance()的唯一好处是:

  1. 您将有一个地方可以捆绑该片段使用的所有参数,并且不必在每次实例化一个片段时都在下面编写代码。

     Bundle args = new Bundle(); args.putInt("someInt", someInt); args.putString("someString", someString); // Put any other arguments myFragment.setArguments(args); 
  2. 这是一种告诉其他类它希望忠实工作的参数的好方法(尽管如果片段实例中没有捆绑参数,则您应该能够处理各种情况)。

因此,我的看法是,使用静态newInstance()实例化片段是一种好习惯。

实例化新的Android片段的最佳做法相关推荐

  1. android最佳开发实现_在android开发中使用可访问性最佳做法

    android最佳开发实现 As you know, accessibility is about building products that everyone can use easily and ...

  2. beta应用程序ios_通过构建简单的食谱应用程序来了解iOS最佳做法

    beta应用程序ios by Khoa Pham 通过Khoa Pham 通过构建简单的食谱应用程序来了解iOS最佳做法 (Learn iOS best practices by building a ...

  3. Javascript中的函数重载-最佳做法

    用JavaScript伪造函数重载的最佳方法是什么? 我知道不可能像其他语言一样重载Javascript中的函数. 如果我需要两个函数一起使用foo(x)和foo(x,y,z) ,这是最佳/首选方式: ...

  4. Windows Server 2003 备份和恢复的最佳做法

    客户具有系统的备份 可能有两种 Microsoft Windows Server 2003 的备份:"权威性系统恢复"(ASR) 备份包括群集配置(我们称之为"系统状态备 ...

  5. 编写Dockerfiles的最佳做法

    编写Dockerfiles的最佳做法 Docker可以通过从Dockerfile包含所有命令的文本文件中读取 指令,自动构建图像,以便构建给定图像所需的顺序.Dockerfile坚持一个具体的格式,并 ...

  6. 分配的访问权限的展台应用:最佳做法

    原文: 分配的访问权限的展台应用:最佳做法 best practices guidance for developing a kiosk app for assigned access. 在 Wind ...

  7. android 片段,android – 将片段添加到片段中(嵌套片段)

    我想动态地将youtube片段添加到我已经存在的片段中.我使用的代码如下: // setting the Youtube Player Dynamically private int setYoutu ...

  8. 用户身份验证最佳做法清单

    用户身份验证是每个Web应用程序共享的功能. 我们已经实现了很多次,所以很早以前就应该完善它. 然而,错误无时无刻不在发生. 造成这种情况的部分原因是,可能出问题的清单很长. 您可能会错误地存储密码, ...

  9. 异步编程中的最佳做法(Async/Await) --转

    近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支持的信息. 本文旨在作为学习异步编程的"第二步":我假设 ...

最新文章

  1. Maven 的这 7 个问题你思考过没有?
  2. 快讯 | 全球首试5G支持多中心远程协同手术
  3. python找人_python之找最后一个人
  4. 设置窗口置顶_这三个应用,每一个都能让你置顶。
  5. C++ list,STL list
  6. 石子合并(动态规划DP)
  7. 基于 Lerna 管理 packages 的 Monorepo 项目最佳实践
  8. Android自动化测试之使用java调用monkeyrunner(补充篇)
  9. 10款提高工作效率的工具软件,你值得拥有!
  10. 基础软件“好用”指南:必须跨越这两道鸿沟!
  11. 美面魔心伊莉丝:会有蜘蛛之神制裁你
  12. vscode下的vue文件格式化
  13. PHICOMM(斐讯)N1盒子 - Armbian5.77(Debian 9)配置自动连接WIFI无线网络
  14. 资产监测设备中法国配置工具介绍(二)
  15. 网页简单整合Skype
  16. git 查看自己秘钥_Git秘钥问题
  17. Graylog 中文手册 常用功能和问题整理
  18. 基于Python实现的孤立词语音识别系统
  19. 无线突然断开无法连接服务器,为什么我的无线网突然就断了 随后怎么也连不上...
  20. 关于STM32平衡小车的几个关键疑问

热门文章

  1. Caffe学习笔记2--Ubuntu 14.04 64bit 安装Caffe(GPU版本)
  2. 开源论坛之discourse搭建
  3. 部署Nginx+Keepalived
  4. 企业内部IT报修是如何操作的?
  5. 【LOJ2127】「HAOI2015」按位或
  6. 7.1.21 jQuery 的 Post请求
  7. django(权限、认证)系统——用户Login,Logout
  8. 【分布式】Zookeeper的服务器角色
  9. 非阻塞同步算法实战(二)-BoundlessCyclicBarrier
  10. [置顶] Lucene开发实例(一般企业搜索平台完全够用全程)