创建片段:构造函数与 newInstance() [英] Creating a Fragment: constructor vs newInstance()

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

问题描述

我最近厌倦了在创建我的 Fragments 时不断需要知道 String 键来将参数传递到 Bundles.所以我决定为我的 Fragments 制作构造函数,它会接受我想要设置的参数,并将这些变量放入带有正确 StringBundles> 键,因此无需其他 FragmentsActivity 需要知道这些键.

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];
    }
}

但是,Lint 对此提出异议,说不要将 Fragment 的子类与带有其他参数的构造函数一起使用,要求我使用 @SuppressLint("ValidFragment")甚至运行应用程序.问题是,这段代码工作得很好.我可以使用 ImageRotatorFragment(int imageResourceId) 或老派方法 ImageRotatorFragment() 并手动调用 setArguments() .当 Android 需要重新创建 Fragment(方向更改或内存不足)时,它会调用 ImageRotatorFragment() 构造函数,然后将相同的参数 Bundle 与我的值一起传递,这些值被设置正确.

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.

所以我一直在寻找建议"的方法,看到了很多使用 newInstance() 来创建带有参数的 Fragments 的例子,这似乎是一样的我的构造函数是什么.所以我自己做了一个测试,它和以前一样完美,没有 Lint 抱怨它.

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;
}

我个人发现使用构造函数比知道使用 newInstance() 和传递参数更常见.我相信你可以在活动中使用同样的构造器技术,Lint 不会抱怨它.所以基本上我的问题是,为什么 Google 不希望您使用带有 Fragments 参数的构造函数?

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?

我唯一的猜测是你不要尝试在不使用 Bundle 的情况下设置实例变量,当 Fragment 被重新创建时,它不会被设置.通过使用 static newInstance() 方法,编译器不会让您访问实例变量.

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?

推荐答案

我个人发现使用构造函数比知道使用 newInstance() 和传递参数更常见.

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.

所以基本上我的问题是,为什么 Google 不希望您使用带有 Fragment 参数的构造函数?

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

您回答了自己的问题:

我唯一的猜测是你不要尝试在不使用 Bundle 的情况下设置实例变量,当 Fragment 被重新创建时它不会被设置.

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.

正确.

我仍然觉得这不足以成为禁止在构造函数中使用参数的理由.

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

欢迎您发表意见.欢迎您以每个构造函数或每个工作区的方式禁用此 Lint 检查.

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

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

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