2012-01-30 30 views
10

Trong example khi sử dụng các đoạn trong tài liệu Android, khi ứng dụng ở chế độ 'chế độ xem hai lần', đoạn chi tiết được tạo lại bất cứ khi nào ứng dụng cần hiển thị chi tiết cho một tiêu đề khác. FragmentTransaction.replace() được sử dụng để hoán đổi từng chi tiết mảnh vụn cũ với mẫu mới.Ok để cập nhật các đoạn thay vì tạo các phiên bản mới?

Thực tiễn này có được khuyến cáo không? Không phải là lãng phí khi tạo ra một cá thể UI mới khi ý định thực sự (không có ý định chơi chữ) là cập nhật những gì UI hiển thị, không phải là giao diện người dùng. Dường như với tôi lý do duy nhất để tạo ra các cá thể mới là nếu một người dự định thêm chúng vào hậu trường để người dùng có thể truy xuất các bước. Nếu không, có an toàn không/nên cập nhật một đoạn trực tiếp?

Trong trường hợp của ví dụ, nó có nghĩa là phương pháp dọc theo các dòng DetailsFragment.setShownIndex(). Điều này sẽ được gọi, chuyển qua chỉ mục tiêu đề mới thay vì tạo lại DetailsFragment.

Giả sử chúng ta có phiên bản ví dụ trong đó một hoạt động quản lý cả hai đoạn, nhưng chỉ hiển thị từng đoạn một, hoán đổi từng đoạn ra khi cần. Nó sẽ được ok cho các hoạt động để tạo ra một thể hiện của từng mảnh, giữ lại tài liệu tham khảo cho mỗi mảnh, và sau đó chỉ cần thêm hoặc loại bỏ hai trường hợp này từ chính nó khi cần thiết?

Một hậu quả có thể xảy ra là, khi đoạn tiêu đề ở trạng thái resumed (nghĩa là trong 'tiền cảnh'), chọn tiêu đề sẽ dẫn đến cuộc gọi đến DetailsFragment.setShownIndex() tại thời điểm đoạn chi tiết nằm trong Trạng thái stopped.

Ý tưởng hay? Ý tưởng tồi?

Xin cảm ơn trước.

Trả lời

5

Như bạn đã nói, lý do chính để tạo các bản sao Fragment mới là dễ sử dụng ngăn xếp ngược. Nó cũng là hoàn toàn an toàn để tái sử dụng một mảnh hiện có (tìm kiếm nó lên bằng cách sử dụng hoặc FragmentManager.findFragmentById() hoặc FragmentManager.findFragmentByTag()). Đôi khi, bạn cần tận dụng tốt các phương pháp Phân đoạn như isVisible(), isRemoving() v.v. để bạn không tham chiếu bất hợp pháp các thành phần giao diện người dùng khi DetailsFragmentstopped.

Dù sao trong Hoạt động một cửa được đề xuất với 2 đoạn, phương thức setShownIndex của bạn có thể đặt trường riêng tư ở DetailsFragment được tải trong onCreateView hoặc onActivityCreated.

ví dụ

DetailsFragment df = getFragmentManager().findFragmentByTag("details"); 
if (df != null) { 
    df.setShownIndex(getSelectedIndex()); 
} else { 
    df = DetailsFragment.newInstance(getSelectedIndex()); 
} 
fragmentTransaction.replace(R.id.frame, df, "details").commit(); 

Trong cả hai trường hợp, cho dù df mới được tạo ra hoặc tái sử dụng, onCreateViewonActivityCreated sẽ được gọi khi DetailsFragment được thêm vào container.

Nhưng nếu bạn muốn ngăn xếp lại, tôi khuyên bạn chỉ nên tạo các phiên bản mới, nếu không bạn chỉ đang triển khai ngăn xếp lưng của riêng mình cho nội dung của DetailsFragment.

0

Tôi đã thử đoạn code sau đây và nó làm việc cho tôi:

private void replaceFragment(Class fragmentClass, String FRAGMENT_NAME, android.support.v4.app.FragmentManager fragmentManager) { 

    Fragment fragment = null; 
    String backStateName = fragmentClass.getName(); // nome della classe del Fragment 

    Log.d("Fragment: ", "Creazione Fragment: "+backStateName); 


    Boolean fragmentExit = isFragmentInBackstack(fragmentManager, backStateName); 


    if (fragmentExit) { //Il Fragment è presente nello stacback 

     // Fragment exists, go back to that fragment 
     //// you can also use POP_BACK_STACK_INCLUSIVE flag, depending on flow 
     fragmentManager.popBackStackImmediate(fragmentClass.getName(), 0); 

    } else { 

     // se non esiste lo aggiungiamo 
     try { 
      fragment = (Fragment) fragmentClass.newInstance(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     // Inizializzo la transazione del Fragment 
     android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction(); 
     ft.setCustomAnimations(
       R.anim.fragment_slide_left_enter, 
       R.anim.fragment_slide_left_exit, 
       R.anim.fragment_slide_right_enter, 
       R.anim.fragment_slide_right_exit); 
     ft.replace(R.id.frameLayout_contentMain, fragment, FRAGMENT_NAME); 
     ft.addToBackStack(fragmentClass.getName()); 
     ft.commit(); 

     // Recupero il numero di Fragment presenti 
     Integer nFragment = fragmentManager.getBackStackEntryCount(); 

     Log.d("Fragment: ", "Numero di Fragment: "+nFragment); 

    } 

} 

Để xác định xem các Fragment là đã có trong StackBack thực hiện chức năng này:

public static boolean isFragmentInBackstack(final android.support.v4.app.FragmentManager fragmentManager, final String fragmentTagName) { 
    for (int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++) { 
     if (fragmentTagName.equals(fragmentManager.getBackStackEntryAt(entry).getName())) { 
      return true; 
     } 
    } 
    return false; 
} 

Tôi Hy vọng tôi có thể giúp bạn

+0

sẽ hữu ích hơn nếu bạn cung cấp nhận xét bằng tiếng Anh –

+0

Tôi xin lỗi. Tôi là người Ý. –

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