创建片段:构造函数与newInstance()

Ste*_*yle 54 android constructor default-constructor android-fragments

我最近厌倦了在创建我的时候经常不知道String要传递参数的键.所以,我决定把我的构造函数,将采取我想设置的参数,并把这些变量到用正确的按键,因此省去了其他的需求和需要知道这些密钥.BundlesFragmentsFragmentsBundlesStringFragmentsActivities

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);
}
Run Code Online (Sandbox Code Playgroud)

然后我像平常一样提出这些论点.

@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];
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,Lint对此提出了疑问,说没有Fragment带有其他参数的构造函数的子类,要求我使用@SuppressLint("ValidFragment")甚至运行应用程序.问题是,这段代码完全正常.我可以使用ImageRotatorFragment(int imageResourceId)旧学校方法ImageRotatorFragment()setArguments()手动调用它.当Android需要重新创建Fragment(方向更改或低内存)时,它会调用ImageRotatorFragment()构造函数,然后Bundle使用我的值传递相同的参数,这些值将被正确设置.

所以我一直在寻找"建议"的方法,并看到很多使用参数newInstance()创建的例子Fragments,这似乎与我的构造函数做同样的事情.所以我自己做了测试,它和以前一样完美无缺,减去Lint抱怨它.

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

    mImageResourceId = imageResourceId;
}
Run Code Online (Sandbox Code Playgroud)

我仍然觉得这不足以让我们不允许在构造函数中使用参数.其他人对此有所了解吗?

Com*_*are 60

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

工厂方法模式在现代软件开发中使用相当频繁.

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

你是在自问自答:

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

正确.

我仍然觉得这不足以让我们不允许在构造函数中使用参数.

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