Gần đây tôi đã mệt mỏi vì phải liên tục biết các khóa String
để chuyển đối số vào Bundles
khi tạo Fragments
của mình. Vì vậy, tôi quyết định tạo các hàm tạo cho số Fragments
để lấy các tham số mà tôi muốn đặt và đặt các biến đó vào Bundles
với các khóa String
chính xác, do đó loại bỏ nhu cầu cho các mã khác Fragments
và Activities
.Tạo phân đoạn: hàm tạo 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);
}
Và sau đó tôi rút ra những đối số như bình thường.
@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];
}
}
Tuy nhiên, Lint mất vấn đề với điều này, nói rằng không có lớp con của Fragment
với nhà thầu với các thông số khác, đòi hỏi tôi phải sử dụng @SuppressLint("ValidFragment")
thậm chí chạy ứng dụng. Vấn đề là, mã này hoạt động hoàn toàn tốt đẹp. Tôi có thể sử dụng ImageRotatorFragment(int imageResourceId)
hoặc phương pháp học cũ ImageRotatorFragment()
và gọi số setArguments()
theo cách thủ công trên đó. Khi Android cần tạo lại Fragment (thay đổi định hướng hoặc bộ nhớ thấp), nó gọi hàm tạo ImageRotatorFragment()
và sau đó chuyển cùng một đối số Bundle
với các giá trị của tôi, được đặt chính xác. Vì vậy, tôi đã tìm kiếm cách tiếp cận "được đề xuất" và thấy rất nhiều ví dụ sử dụng newInstance()
để tạo ra Fragments
với các tham số, điều này dường như làm điều tương tự mà nhà xây dựng của tôi là. Vì vậy, tôi đã tự mình thử nghiệm nó, và nó hoạt động hoàn hảo như trước đây, trừ đi Lint rên rỉ về nó.
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;
}
Cá nhân tôi thấy rằng việc sử dụng hàm tạo phổ biến hơn nhiều so với việc biết sử dụng newInstance()
và tham số truyền. Tôi tin rằng bạn có thể sử dụng kỹ thuật xây dựng tương tự này với các hoạt động và Lint sẽ không phàn nàn về nó. Vì vậy, về cơ bản câu hỏi của tôi là, tại sao Google không muốn bạn sử dụng các nhà xây dựng với các tham số cho Fragments
?
Đoán duy nhất của tôi là bạn không cố gắng đặt biến mẫu mà không sử dụng Bundle
, sẽ không được đặt khi Fragment
được tạo lại. Bằng cách sử dụng phương thức static newInstance()
, trình biên dịch sẽ không cho phép bạn truy cập một biến mẫu.
public ImageRotatorFragment(int imageResourceId) {
Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");
mImageResourceId = imageResourceId;
}
Tôi vẫn không cảm thấy như vậy là đủ lý do để không cho phép sử dụng thông số trong nhà thầu. Bất cứ ai khác có cái nhìn sâu sắc về điều này?