2013-08-15 24 views
27

Tôi biết về mẫu "newInstance" (Best practice for instantiating a new Android Fragment). Nhưng làm thế nào để tôi cập nhật các đối số của một mảnh ví dụ nếu một đoạn khác thay đổi dữ liệu?Thực tiễn tốt nhất để cập nhật đối số của một đoạn?

Tôi biết về các phương thức gọi lại giữa các Phân đoạn/Hoạt động, nhưng các cuộc gọi lại này sẽ không cập nhật các đối số ?!

Ví dụ: khi tạo đoạn mã, tôi chuyển URI cho nó bằng gói. Sau đó, một đoạn khác thay đổi URI này bằng cách gọi phương thức changeUri (Uri uri) trên đoạn đầu tiên. Nếu sau đó đoạn được tạo lại (ví dụ do xoay màn hình), nó sẽ sử dụng URI đầu tiên từ gói đối số thay vì uri cập nhật sau, đúng không?

Cách tốt nhất để giải quyết vấn đề này là gì? Tôi có phải lưu trữ thủ công nó trong savedInstanceState và về cách sử dụng quyết định có sử dụng instanceState hoặc các đối số-bundle không?

Tôi đang tìm kiếm một cách tiêu chuẩn xử lý các đối số của các mảnh vỡ của tôi, vì vậy tôi nghĩ rằng tôi sẽ có một cách tiếp cận như vậy (pseudo-code):

private Uri arg1; 

public static Fragment newInstance(Uri arg1) { 
    create bundle 
    create fragment instance 
    set bundle to fragment 
    return fragment 
} 

private void onCreate(Bundle savedInstance) { 
    if(savedInstance != null) { 
    arg1 = savedInstance.uri 
    } 
} 

private Uri getUri() { 
    if(arg1 == null) { 
    arg1 = getArguments.uri 
    } 
    if(arg1 == null) { 
    arg1 = defaultValue 
    } 
} 

Vì vậy, tôi có một cách đơn giản nhất cách để truy cập đối số của tôi. Và không cần phải sử dụng if-else-hassle, mỗi khi tôi cần lập luận đó.

Bạn nghĩ sao về điều này?

+0

Có. Có bao nhiêu mã đang nói về? Phương thức oveeriden -'onSaveInstanceState'- với 1 dòng phụ và câu lệnh if-else trong 'onCreate'? – gunar

+0

thất bại thiết kế các mảnh vỡ không nên phụ thuộc vào các mảnh khác – danny117

+0

Điều gì về để 'viết lại' các đối số trong một phương pháp công cộng của đoạn đó? –

Trả lời

16

Bạn không thể thay đổi đối số sau khi đặt và Fragment được thêm vào Activity, tôi đã sử dụng cách tiếp cận tương tự mà bạn đã tự xác định. Lần đầu tiên tôi kiểm tra các Bundle thông qua để onCreate() nếu nó không null tôi sử dụng nó, nhưng nếu null của nó sau đó tôi sử dụng các đối số. Và tôi lưu bất kỳ dữ liệu mới nhất nào trong onSaveInstanceState(). Để biết thêm chi tiết: Is it possible to pass arguments to a fragment after it's been added to an activity?

+1

Tôi rất muốn giới thiệu cho OP để đặt câu trả lời này là câu trả lời để cung cấp tín dụng phù hợp. –

4

Bạn lưu trạng thái giống như cách bạn thực hiện cho Hoạt động trong gọi lại onSaveInstanceState của Fragment. Nếu bạn đã cập nhật URI kể từ lần cuối cùng onCreate(), bạn sẽ lưu trữ URI được cập nhật trong Bundle và sẽ nhận lại số này trong onCreate(). Trạng thái lưu là chính xác những gì được thiết kế này, và bằng cách thay đổi URI, tất cả những gì bạn đã làm là thay đổi trạng thái.

0

Tùy thuộc vào cách bạn đang sử dụng các đoạn của bạn có thể xác định hiệu quả của chiến lược đó. Ví dụ: nếu bạn có nhiều đoạn trong mẫu trang/tab xem thông thường và đang quản lý chúng bằng FragmentStatePagerAdapter, có thể có cơ hội cho hoạt động của bạn hoặc các đoạn khác tham chiếu một thể hiện phân đoạn không còn tồn tại gây ra một null nữa. ngoại lệ con trỏ. Một cách mà bạn có thể giải quyết vấn đề này, nếu bạn không muốn viết lời gọi lại, hãy sử dụng Intents và BroadcastReceivers (có thể hơi quá mức và khó quản lý nhưng nếu được thực hiện đúng cách có thể tiết kiệm được nhiều đau đầu). theo kinh nghiệm của tôi) để gửi và nhận các chương trình phát sóng đến và từ hoạt động của phụ huynh.

Điều tuyệt vời về ý định là chúng có thể được điều chỉnh để hoạt động vào những thời điểm cụ thể và chấp nhận nhiều tính năng bổ sung dữ liệu bao gồm các gói và đối tượng có thể gửi bưu kiện.

1

Best practice for updating arguments of a fragment: Tại sao chúng ta cần thêm lập luận By NewInstance() phương pháp & lý do tại sao nó là thực hành tốt nhất cho mảnh?

Phân đoạn có thể được coi là phần mô-đun của hoạt động. Điều này có nghĩa là khi chúng ta tạo ra một mảnh, chúng ta cần phải làm cho nó trở thành mô-đun & độc lập.

Giả sử bạn cần một đoạn mà cần một cuộc tranh luận để operate.We cũng có thể viết nó

MyFragmentClass mFrag = new MyFragmentClass(); 
Bundle bundle = new Bundle(); 
bundle.putString("key", value); 
mFrag.setArguments(bundle); 

Nó cũng hoạt động tốt & bạn có thể nhận lập luận onCreate phương pháp. Đây là sự khác biệt mà bạn cũng có thể tạo ra một thể hiện của mảnh mà không có đối số và thêm nó vào trình quản lý mảnh nhưng mảnh của bạn cần đối số để hoạt động. Thêm phương thức newInstance vào nhà phát triển lực lượng mảnh để thêm đối số trong khi tạo. Đó là lý do tại sao nó được cho là thực hành tốt nhất.

Trong vấn đề của bạn, bạn có thể sử dụng setRetainInstance(boolean retain) ngăn chặn đoạn của bạn không phá hủy khi hoạt động bị hủy.

4

tôi chỉ cần thay đổi giá trị trong bó Ví dụ:

synchronized (fragment.getArguments()) { 
     fragment.getArguments().putInt(KEY, new Value); 
    } 

Và cập nhật nội dung với Đối số mới

+3

Tại sao được đồng bộ hóa? –

+0

có lý do đồng bộ hóa được sử dụng? –

0

Trong trường hợp bạn muốn sử dụng lại một đoạn nhưng cần phải cập nhật những lập luận, bạn cần phải sử dụng fragment.getArguments(). PutAll (bundle);

private static void setInspireByDoArguments(DoOptionsFragment fragment, long doId) { 
    Bundle bundle = new Bundle(); 
    bundle.putLong(Constants.EXTRA_DO_ID, doId); 
    bundle.putInt(Constants.EXTRA_DO_OPTIONS_DIALOG_MODE, MODE_GET_INSPIRE_BY_DO); 
    if (fragment.getArguments() != null) { 
     fragment.getArguments().putAll(bundle); 
    } else 
     fragment.setArguments(bundle); 
} 

//This is how I managed to Check if the fragment exist and update the arguments. 

public static void showDoInspireDialog(FragmentManager fragmentManager, long doId, DoOptionsFragment.DoOptionCallBack callBack) { 
    DoOptionsFragment doOptionsFragment = (DoOptionsFragment) fragmentManager.findFragmentByTag("do_options_fragment"); 
    if (doOptionsFragment == null) { 
     doOptionsFragment = DoOptionsFragment.getInspiredByDoInstance(doId, callBack); 
     fragmentManager.beginTransaction() 
       .add(doOptionsFragment, "do_options_fragment") 
       .commit(); 
    } else { 
     doOptionsFragment.setCallBack(callBack); 
     setInspireByDoArguments(doOptionsFragment, doId); 
     doOptionsFragment.showInspireByDoDialog(doId); 
    } 
} 

    public static DoOptionsFragment getInspiredByDoInstance(long doId, DoOptionsFragment.DoOptionCallBack callBack) { 
    DoOptionsFragment doOptionsFragment = new DoOptionsFragment(); 
    setInspireByDoArguments(doOptionsFragment, doId); 
    doOptionsFragment.setCallBack(callBack); 
    return doOptionsFragment; 
} 
+0

'fragment.setArguments (bundle)' có thể tạo ra 'java.lang.IllegalStateException' nếu bạn chuyển trở lại đoạn hiện có trong Activity – StAlex

Các vấn đề liên quan