2013-02-01 18 views
54

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 FragmentsActivities.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?

Trả lời

59

Cá nhân tôi thấy rằng việc sử dụng hàm tạo là thực tiễn phổ biến hơn nhiều so với việc biết sử dụng newInstance() và tham số truyền.

factory method pattern được sử dụng khá thường xuyên trong phát triển phần mềm hiện đại.

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à thầu có tham số cho Phân đoạn?

Bạn đã trả lời câu hỏi của riêng bạn:

đoán duy nhất của tôi là vì vậy bạn không cố gắng thiết lập một biến dụ mà không sử dụng Bundle, mà sẽ không nhận được thiết lập khi các Fragment được tái tạo.

Đúng.

Tôi vẫn không cảm thấy như thế này là đủ lý do để không cho phép sử dụng thông số trong các nhà xây dựng.

Bạn được hoan nghênh ý kiến ​​của mình. Bạn được hoan nghênh để vô hiệu hóa kiểm tra Lint này, trên một nhà xây dựng cho mỗi nhà xây dựng hoặc cho mỗi không gian làm việc.

0

Android chỉ tạo lại các đoạn mà nó giết bằng cách sử dụng hàm tạo mặc định, vì vậy bất kỳ khởi tạo nào chúng ta làm trong các hàm tạo bổ sung sẽ bị mất. Dữ liệu bị mất sẽ bị mất.