Sự khác biệt giữa getSupportFragmentManager () và getChildFragmentManager () là gì?


78

Lớp của tôi kế thừa Fragment và đó là lý do tại sao nó không thể sử dụng getSupportFragmentManager (). Tôi đang sử dụng getChildFragmentManager và nó hiển thị cho tôi Lỗi - IllegalArguementException: Không tìm thấy chế độ xem cho lỗi id ....

Bất kỳ hướng dẫn sẽ được đánh giá cao.

Mã để gọi AttachmentsListFragment mới là

Bundle b = new Bundle();
b.putSerializable("AttachmentsList", msg.attachments);  
        AttachmentListFragment listfrag = new AttachmentListFragment(msg.attachments);
FragmentTransaction transaction = getFragmentManager().beginTransaction();       
transaction.add(R.id.attachmentslistcontainer, listfrag);
transaction.addToBackStack(null);
transaction.commit();

Attmentslayout.xml là

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/attachmentslistcontainer"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textViewAttachmentHeader"
        style="@style/Normal.Header.Toolbar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/list_separator_background"
        android:ellipsize="end"
        android:gravity="center"
        android:maxLines="2"
        android:text="@string/attachments_header"
        android:textColor="#FFFFFFFF"
        android:textSize="22sp"
        android:textStyle="bold"
        android:visibility="visible" />

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>

</FrameLayout>

AttachmentsListFragment.java

public class AttachmentListFragment extends ListFragment implements IAttachmentsData {

    ArrayList<Attachments> items = null;
    Integer cellLayoutID;
    Integer index;

    public AttachmentListFragment() {

    }

    public AttachmentListFragment(ArrayList<Attachments> items) {
        this.items = items;
        Log.i("Logging", "Items size" + items.size()); //$NON-NLS-1$
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle bundle;
        if (savedInstanceState != null) {
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        //super.onCreateView(inflater, container, savedInstanceState);

        //  setContentView(R.layout.attachmentslayout);
        View view = inflater.inflate(R.layout.attachmentslayout, container, false);
        return view;
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setListAdapter(new AttachmentAdapter(
                getActivity().getApplicationContext(),
                R.layout.attachmentslistcellcontent,
                items));
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);
        index = position;
        Intent intent = new Intent();
        Bundle b = new Bundle();
        b.putByteArray("Data", items.get(position).getImageData());
        intent.putExtras(b);
    }


    public byte[] getData() {
        // TODO Auto-generated method stub
        if (items != null && index < items.size()) {

            return items.get(index).getImageData();
        }
            return null;
    }

}

2
Vui lòng đăng toàn bộ phương thức và / hoặc lớp mà bạn đang gọi "getChildFragmentManager".
WindyB

Câu trả lời:


154

Định nghĩa của getChildFragmentManager()là:

Trả về FragmentManager riêng tư để đặt và quản lý các Fragment bên trong Fragment này.

Trong khi đó định nghĩa của getFragmentManager()(hoặc trong trường hợp này getSupportFragmentManager()) là:

Trả lại FragmentManager để tương tác với các phân đoạn được liên kết với hoạt động của phân mảnh này.

Về cơ bản, sự khác biệt là Fragment hiện có nội bộ riêng FragmentManagercó thể xử lý Fragment. FragmentManager con là trình xử lý các Fragment chỉ chứa trong Fragment mà nó được thêm vào. FragmentManager khác được chứa trong toàn bộ Activity.

Trong trường hợp này, điều tôi đoán là bạn đã thêm các Phân đoạn vào Trình quản lý phân mảnh của Hoạt động. Bạn nhận được FragmentManager con không chứa những gì bạn đang tìm kiếm. Do đó, bạn nhận được ngoại lệ vì nó không thể tìm thấy Fragment với ID đã cho vì nó nằm trong FragmentManager khác.


3
Tôi đã thử sử dụng getChildFragmentManager. Nhưng nó cũng cho thấy ngoại lệ tương tự
NinjaCoder

1
Tôi nghĩ bạn nói rằng bạn đã sử dụng getChildFragmentManager.
DeeV

nếu tôi sử dụng getSupportFragmentManager để tạo một phân đoạn con để cha giữ con và cả hai đều hiển thị / trong nền trước, thì nút quay lại làm gì? nó có bật ra khỏi cha mẹ không? hay đứa trẻ? Vân vân.?
lv99Zubat

1
@Rai getSupportFragmentManagergetFragmentManagerđều là người quản lý phân khúc ở cấp cao nhất Activity. Phân đoạn bạn thêm về mặt kỹ thuật không phải là "phân đoạn con" theo định nghĩa được mô tả ở đây. Chúng là các Fragment do Activity xử lý. Bất kỳ Fragment nào bạn đăng trên backstack của một trong hai người quản lý được Activity xử lý sẽ được bật ra ở "back".
DeeV

25

getFragmentManagerthuộc về thuộc Activity
getChildFragmentManagervềFragment

Ví dụ chúng ta có một ứng dụng mà có MainActivity, Fragment1, Fragment2, container_view_on_mainlà một cách bố trí trongactivty_main.xml

ĐỂ hiển thị Fragment1 trên MainActivitychúng ta phải sử dụnggetSupportFragmentManager()

getSupportFragmentManager().beginTransaction().replace(R.id.container_view_on_main, Fragment1.newInstance());

ĐỂ hiển thị Fragment2 từ Fragment1chúng tôi có 2 cách

SỬ DỤNG getFragmentManager()

getFragmentManager().beginTransaction().replace(R.id.container_view_on_main, Fragment1.newInstance());

SỬ DỤNG getChildFragmentManager()

Đầu tiên, chúng ta phải tạo một bố cục với id container_view_on_fragment1bên trong fragment1.xml, sau đó

getChildFragmentManager().beginTransaction().replace(R.id.container_view_on_fragment1, Fragment2.newInstance()).commit();

PHẦN KẾT LUẬN

Trong bản demo này, tôi nghĩ chúng ta nên sử dụng getFragmentManager()khi go from Fragment1to Fragment2vì nó đơn giản và tốt cho hiệu suất ( Fragment1sẽ dừng khi Fragment2mở)

Khi chúng tôi sử dụng getChildFragmentManager()?
Ví dụ bạn MainActivitycó một ViewPagercái có 3 trang, bên trong mỗi trang bạn cần thay thế một số đoạn.

THÊM
- getParentFragment ()
getFragmentManager() => trả về null
getChildFragmentManager() => luôn trả về phân đoạn gốc ( Fragment1trong bản demo ngay cả khi chúng ta đi đến Fragment3,, ...)

Câu trả lời này dựa trên sự hiểu biết của tôi vì vậy xin vui lòng sửa cho tôi nếu tôi sai. Hy vọng nó sẽ giúp


2

Nếu bạn muốn có một phân đoạn hoạt động như một vùng chứa các phân đoạn, bạn phải sử dụng phương thức getChildFragmentManager của phân đoạn. Nếu bạn sử dụng getSupportFragmentManager, về cơ bản, bạn sẽ sử dụng trình quản lý phân đoạn hoạt động theo cách của vòng đời hoạt động, chứ không phải theo cách phân đoạn của bạn.

Ví dụ, tôi có một phân đoạn chứa ViewPager - nó được gọi là CollectionsFragment. Vì vậy, tôi đã có 3 phân đoạn được hiển thị dưới dạng các tab trong đó: AllCollectionsFragment, MyCollectionsFragment, FavouriteCollectionsFragment. Và tôi đã đưa getActivity (). GetSupportFragmentManager () cho FragmentStatePagerAdapter mà tôi đang sử dụng.

Vì vậy, điều này đã gây ra hành vi sau - các phương thức onDestroyView / onDestroy / onDetach / onStop của 3 đoạn tab không được gọi. Khi tôi chuyển sang sử dụng getChildFragmentManager, mọi thứ đều ổn.

Nếu bạn muốn, bạn có thể kiểm tra tài liệu cho hai phương pháp:

getChildFragmentManager (): Trả về một FragmentManager riêng để đặt và quản lý các Fragment bên trong Fragment này.

getSupportFragmentManager (): Trả lại FragmentManager để tương tác với các phân mảnh được liên kết với hoạt động của phân mảnh này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.