实例化新的Android片段的最佳做法
我已经看到了两种在应用程序中实例化新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
是由系统重新创建的,它也允许您someInt
从getArguments()
获取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()
的唯一好处是:
您将有一个地方可以捆绑该片段使用的所有参数,并且不必在每次实例化一个片段时都在下面编写代码。
Bundle args = new Bundle(); args.putInt("someInt", someInt); args.putString("someString", someString); // Put any other arguments myFragment.setArguments(args);
这是一种告诉其他类它希望忠实工作的参数的好方法(尽管如果片段实例中没有捆绑参数,则您应该能够处理各种情况)。
因此,我的看法是,使用静态newInstance()
实例化片段是一种好习惯。
实例化新的Android片段的最佳做法相关推荐
- android最佳开发实现_在android开发中使用可访问性最佳做法
android最佳开发实现 As you know, accessibility is about building products that everyone can use easily and ...
- beta应用程序ios_通过构建简单的食谱应用程序来了解iOS最佳做法
beta应用程序ios by Khoa Pham 通过Khoa Pham 通过构建简单的食谱应用程序来了解iOS最佳做法 (Learn iOS best practices by building a ...
- Javascript中的函数重载-最佳做法
用JavaScript伪造函数重载的最佳方法是什么? 我知道不可能像其他语言一样重载Javascript中的函数. 如果我需要两个函数一起使用foo(x)和foo(x,y,z) ,这是最佳/首选方式: ...
- Windows Server 2003 备份和恢复的最佳做法
客户具有系统的备份 可能有两种 Microsoft Windows Server 2003 的备份:"权威性系统恢复"(ASR) 备份包括群集配置(我们称之为"系统状态备 ...
- 编写Dockerfiles的最佳做法
编写Dockerfiles的最佳做法 Docker可以通过从Dockerfile包含所有命令的文本文件中读取 指令,自动构建图像,以便构建给定图像所需的顺序.Dockerfile坚持一个具体的格式,并 ...
- 分配的访问权限的展台应用:最佳做法
原文: 分配的访问权限的展台应用:最佳做法 best practices guidance for developing a kiosk app for assigned access. 在 Wind ...
- android 片段,android – 将片段添加到片段中(嵌套片段)
我想动态地将youtube片段添加到我已经存在的片段中.我使用的代码如下: // setting the Youtube Player Dynamically private int setYoutu ...
- 用户身份验证最佳做法清单
用户身份验证是每个Web应用程序共享的功能. 我们已经实现了很多次,所以很早以前就应该完善它. 然而,错误无时无刻不在发生. 造成这种情况的部分原因是,可能出问题的清单很长. 您可能会错误地存储密码, ...
- 异步编程中的最佳做法(Async/Await) --转
近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支持的信息. 本文旨在作为学习异步编程的"第二步":我假设 ...
最新文章
- Maven 的这 7 个问题你思考过没有?
- 快讯 | 全球首试5G支持多中心远程协同手术
- python找人_python之找最后一个人
- 设置窗口置顶_这三个应用,每一个都能让你置顶。
- C++ list,STL list
- 石子合并(动态规划DP)
- 基于 Lerna 管理 packages 的 Monorepo 项目最佳实践
- Android自动化测试之使用java调用monkeyrunner(补充篇)
- 10款提高工作效率的工具软件,你值得拥有!
- 基础软件“好用”指南:必须跨越这两道鸿沟!
- 美面魔心伊莉丝:会有蜘蛛之神制裁你
- vscode下的vue文件格式化
- PHICOMM(斐讯)N1盒子 - Armbian5.77(Debian 9)配置自动连接WIFI无线网络
- 资产监测设备中法国配置工具介绍(二)
- 网页简单整合Skype
- git 查看自己秘钥_Git秘钥问题
- Graylog 中文手册 常用功能和问题整理
- 基于Python实现的孤立词语音识别系统
- 无线突然断开无法连接服务器,为什么我的无线网突然就断了 随后怎么也连不上...
- 关于STM32平衡小车的几个关键疑问
热门文章
- Caffe学习笔记2--Ubuntu 14.04 64bit 安装Caffe(GPU版本)
- 开源论坛之discourse搭建
- 部署Nginx+Keepalived
- 企业内部IT报修是如何操作的?
- 【LOJ2127】「HAOI2015」按位或
- 7.1.21 jQuery 的 Post请求
- django(权限、认证)系统——用户Login,Logout
- 【分布式】Zookeeper的服务器角色
- 非阻塞同步算法实战(二)-BoundlessCyclicBarrier
- [置顶] Lucene开发实例(一般企业搜索平台完全够用全程)