创建一个片段:构造VS的newInstance() [英] Creating a Fragment: constructor vs newInstance()

查看:173
本文介绍了创建一个片段:构造VS的newInstance()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我厌倦了不断不必知道字符串键将参数传递到捆绑创建时,我的片段。所以,我决定把构造为我的片段,将采取我想设置的参数,并把这些变量放入捆绑用正确的字符串键,因此省去了其他片段活动需要知道这些密钥。

 公共ImageRotatorFragment(){
    超();
    Log.v(TAG,ImageRotatorFragment());
}

公共ImageRotatorFragment(INT imageResourceId){
    Log.v(TAG,ImageRotatorFragment(中间体imageResourceId));

    //获取参数传入,如果有的话
    捆绑的args = getArguments();
    如果(参数== NULL){
        的args =新包();
    }
    //添加参数,该参数捆绑
    args.putInt(KE​​Y_ARG_IMAGE_RES_ID,imageResourceId);
    setArguments(参数);
}
 

然后我拉出来这些参数正常人一样。

  @覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    Log.v(TAG的onCreate);

    //设置传入的参数
    捆绑的args = getArguments();
    如果(参数!= NULL){
        mImageResourceId = args.getInt(KE​​Y_ARG_IMAGE_RES_ID,StaticData.getImageIds()[0]);
    }
    其他 {
        //默认图像资源的第一图像
        mImageResourceId = StaticData.getImageIds()[0];
    }
}
 

不过,皮棉了问题,这一点,说不要有片段的子类与构造与其他参数,要求我用 @燮pressLint(ValidFragment),即使运行应用程序。问题是,这个code工作完全正常。我可以使用 ImageRotatorFragment(INT imageResourceId)或老派的方法 ImageRotatorFragment()和呼叫 setArguments()就可以了手动。当机器人需要重新创建片段(方向改变或内存不足),它调用 ImageRotatorFragment()的构造函数,然后通过同样的说法捆绑与我的价值观,它得到正确的设置。

所以,我一直在寻找的建议的方式,看到了很多使用的例子的newInstance()以创建片段与参数,这似乎做同样的事情,我的构造函数。所以,我做了我自己去测试它,和它的作品一样完美和以前一样,减去林特抱怨它。

 公共静态ImageRotatorFragment的newInstance(INT imageResourceId){
    Log.v(TAG的newInstance(INT imageResourceId));

    ImageRotatorFragment imageRotatorFragment =新ImageRotatorFragment();

    //获取参数传入,如果有的话
    捆绑的args = imageRotatorFragment.getArguments();
    如果(参数== NULL){
        的args =新包();
    }
    //添加参数,该参数捆绑
    args.putInt(KE​​Y_ARG_IMAGE_RES_ID,imageResourceId);
    imageRotatorFragment.setArguments(参数);

    返回imageRotatorFragment;
}
 

我个人认为使用构造比知道使用的newInstance()和参数传递一个更为普遍的做法。我相信你可以使用带有活动同样的构造技术,林特不会抱怨。 所以基本上我的问题是,为什么谷歌不希望你使用的构造与参数片段

我唯一的猜测是,所以你不要试图在不使用捆绑,它不会得到设置设置一个实例变量,当片段被重新创建。通过使用静态的newInstance()方法,编译器不会让你访问一个实例变量。

 公共ImageRotatorFragment(INT imageResourceId){
    Log.v(TAG,ImageRotatorFragment(中间体imageResourceId));

    mImageResourceId = imageResourceId;
}
 

我仍然不觉得这是足够的理由来禁止在构造函数中使用的参数。任何人都见识到这一点?

解决方案
  

我个人认为使用构造比知道使用的newInstance(),并传递参数一个更普遍的做法。

的使用非常频繁的现代软件开发的工厂方法模式。

  

所以基本上我的问题是,为什么谷歌不希望你使用的构造与参数的片段?

您回答了你自己的问题:

  

我唯一的猜测是,所以你不要试图在不使用捆绑,这不会得到设置时,片段被重新设置一个实例变量。

正确的。

  

我仍然不觉得这是足够的理由来禁止在构造函数中使用的参数。

您,欢迎您的意见。欢迎您禁用此林特检查,无论是在每个构造函数或每个工作区的方式。

I recently grew tired of constantly having to know String keys to pass arguments into Bundles when creating my Fragments. So I decided to make constructors for my Fragments that would take the parameters I wanted to set, and put those variables into the Bundles with the correct String keys, therefore eliminating the need for other Fragments and Activities needing to know those keys.

public ImageRotatorFragment() {
    super();
    Log.v(TAG, "ImageRotatorFragment()");
}

public ImageRotatorFragment(int imageResourceId) {
    Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");

    // Get arguments passed in, if any
    Bundle args = getArguments();
    if (args == null) {
        args = new Bundle();
    }
    // Add parameters to the argument bundle
    args.putInt(KEY_ARG_IMAGE_RES_ID, imageResourceId);
    setArguments(args);
}

And then I pull out those arguments like normal.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v(TAG, "onCreate");

    // Set incoming parameters
    Bundle args = getArguments();
    if (args != null) {
        mImageResourceId = args.getInt(KEY_ARG_IMAGE_RES_ID, StaticData.getImageIds()[0]);
    }
    else {
        // Default image resource to the first image
        mImageResourceId = StaticData.getImageIds()[0];
    }
}

However, Lint took issue with this, saying not to have subclasses of Fragment with constructors with other parameters, requiring me to use @SuppressLint("ValidFragment") to even run the app. The thing is, this code works perfectly fine. I can use ImageRotatorFragment(int imageResourceId) or the old school method ImageRotatorFragment() and call setArguments() manually on it. When Android needs to recreate the Fragment (orientation change or low memory), it calls the ImageRotatorFragment() constructor and then passes the same argument Bundle with my values, which get set correctly.

So I have been searching for the "suggested" approach and see a lot of examples using newInstance() to create Fragments with parameters, which seems to do the same thing my constructor is. So I made my own to test it, and it works just as flawlessly as before, minus Lint whining about it.

public static ImageRotatorFragment newInstance(int imageResourceId) {
    Log.v(TAG, "newInstance(int imageResourceId)");

    ImageRotatorFragment imageRotatorFragment = new ImageRotatorFragment();

    // Get arguments passed in, if any
    Bundle args = imageRotatorFragment.getArguments();
    if (args == null) {
        args = new Bundle();
    }
    // Add parameters to the argument bundle
    args.putInt(KEY_ARG_IMAGE_RES_ID, imageResourceId);
    imageRotatorFragment.setArguments(args);

    return imageRotatorFragment;
}

I personally find that using constructors is a much more common practice than knowing to use newInstance() and passing parameters. I believe you can use this same constructor technique with Activities and Lint will not complain about it. So basically my question is, why does Google not want you to use constructors with parameters for Fragments?

My only guess is so you don't try to set an instance variable without using the Bundle, which won't get set when the Fragment gets recreated. By using a static newInstance() method, the compiler won't let you access an instance variable.

public ImageRotatorFragment(int imageResourceId) {
    Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");

    mImageResourceId = imageResourceId;
}

I still don't feel like this is enough reason to disallow the use of parameters in constructors. Anyone else have insight into this?

解决方案

I personally find that using constructors is a much more common practice than knowing to use newInstance() and passing parameters.

The factory method pattern is used fairly frequently in modern software development.

So basically my question is, why does Google not want you to use constructors with parameters for Fragments?

You answered your own question:

My only guess is so you don't try to set an instance variable without using the Bundle, which won't get set when the Fragment gets recreated.

Correct.

I still don't feel like this is enough reason to disallow the use of parameters in constructors.

You are welcome to your opinion. You are welcome to disable this Lint check, either on a per-constructor or per-workspace fashion.

这篇关于创建一个片段:构造VS的newInstance()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆