2013-02-01 84 views
54

我最近厌倦了不断地必须知道String键来在创建我的Fragments时将参数传入Bundles。所以我决定为我的Fragments制作构造函数,这些构造函数将采用我想要设置的参数,并将这些变量放入Bundles中,使用正确的String键,因此不需要其他FragmentsActivities需要知道这些键。创建片段:构造函数vs newInstance()

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

然后我拿出像正常的参数。

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

然而,林特采取了问题这一点,他说不要有与其他参数的构造函数的Fragment子类,我需要使用@SuppressLint("ValidFragment"),即使运行应用程序。事情是,这段代码工作得很好。我可以使用ImageRotatorFragment(int imageResourceId)或旧学校方法ImageRotatorFragment()并手动调用setArguments()。当Android需要重新创建片段(方向更改或内存不足)时,它会调用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; 
} 

我个人认为使用构造是一个更普遍的做法比知道使用newInstance()和传递参数。我相信你可以在Activities和Lint中使用相同的构造函数技巧,而不会抱怨它。 所以基本上我的问题是,为什么谷歌不希望你使用参数为Fragments的构造函数?

我唯一的猜测是所以你不要试图设置一个实例变量,而不使用Bundle,当Fragment被重新创建时它不会被设置。通过使用static newInstance()方法,编译器不会让您访问实例变量。

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

    mImageResourceId = imageResourceId; 
} 

我仍然不觉得这是足够的理由不允许在构造函数中使用参数。任何人都有这方面的见解?

回答

59

我个人发现使用构造函数比知道使用newInstance()和传递参数更加普遍。

factory method pattern在现代软件开发中使用相当频繁。

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

你回答了自己的问题:

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

正确。

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

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

0

Android只会使用默认的构造函数重新创建它杀死的碎片,因此我们在其他构造函数中执行的任何初始化都将丢失。因此数据将会丢失。