2012-12-07 34 views
29

Cách sử dụng (hoặc "Chúng ta có thể sử dụng") getChildFragmentManager() theo cách lập trình (động) được thêm Fragment s?getChildFragmentManager() trên các phân đoạn được thêm theo chương trình (động)?

Đây là ví dụ của tôi.

Tôi có một MainActivity, một OuterFrag và một InnerFrag. Tôi sẽ thêm OuterFrag vào MainActivity động bởi FragmentManager. Ngoài ra, tôi cũng sẽ thêm InnerFrag vào OuterFrag cũng theo kiểu động FragmentManager. Nhưng tôi muốn thêm InnerFrag chính xác là con của OuterFrag, không thay thế OuterFrag và là con mới của MainActivity.

Tôi muốn giữ phân cấp này: MainActivity -> OuterFrag -> InnerFrag. Vì vậy, MainActivity luôn có thể gọi OuterFrag.

Nhưng KHÔNG thay đổi từ thứ bậc này: MainActivity -> OuterFrag thành phân cấp này: MainActivity -> InnerFragMainActivity sẽ mất OuterFrag.

Đây là mã ví dụ của tôi.

MainActivity.java

package com.example.frag; 

import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 

public class MainActivity extends FragmentActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new OuterFrag()).commit(); 
     getSupportFragmentManager().executePendingTransactions(); 

     System.out.println("Before: " 
       + getSupportFragmentManager().findFragmentById(R.id.frameLayout)); 

     ((OuterFrag) getSupportFragmentManager().findFragmentById(R.id.frameLayout)) 
       .addInnerFrag(); 

     System.out.println("After: " 
       + getSupportFragmentManager().findFragmentById(R.id.frameLayout)); 
    } 
} 

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/frameLayout" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 
</FrameLayout> 

OuterFrag.java

package com.example.frag; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class OuterFrag extends Fragment { 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.outer_frag, container, false); 
    } 

    public void addInnerFrag() { 

     getFragmentManager().beginTransaction().replace(this.getId(), new InnerFrag()).commit(); 
     getFragmentManager().executePendingTransactions(); 

//  getChildFragmentManager().beginTransaction().add(this.getId(), new InnerFrag()).commit(); 
//  getChildFragmentManager().executePendingTransactions(); 
    } 
} 

outer_frag.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/textView1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="i am the OUTER frag" /> 

InnerFrag.java

package com.example.frag; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class InnerFrag extends Fragment { 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.inner_frag, container, false); 
    } 
} 

inner_frag.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/textView2" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="i am the INNER frag" /> 

Hiện nay, các mã trên có thể chạy mà không có lỗi. Nhưng nó thực sự thay đổi InnerFrag là đứa con mới của MainActivity. Điều này có thể được xác nhận bởi hai câu lệnh System Print Out mà đối tượng Before: Object và After: Object được thay đổi. Trong OuterFrag.java, nếu getChildFragmentManager() báo cáo được chạy thay vì getFragmentManager() báo cáo, chúng tôi sẽ nhận được lỗi runtime sau:

12-07 02:29:38.406: E/AndroidRuntime(12051): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.frag/com.example.frag.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f070000 (com.example.frag:id/frameLayout) for fragment InnerFrag{46e32748 #0 id=0x7f070000} 

Sử dụng getChildFragmentManager() là lý thuyết đúng. Nó có thể được sử dụng trong một đoạn không được lập trình bổ sung (có nghĩa là thay đổi <FrameLayout> thành , thêm thuộc tính android:name="com.example.frag.OuterFrag" và xóa câu lệnh getSupportFragmentManager() đầu tiên trong MainActivity.java).Và nó đang giữ đúng hệ thống phân cấp: MainActivity -> OuterFrag -> InnerFrag. Nhưng những lời của mảnh gốc (outer_frag.xml) không bao giờ có thể bị lấy đi.

Tóm lại, tôi muốn tham khảo OuterFrag trong MainActivity luôn. Và tôi muốn OuterFrag hoạt động như một trình giữ chỗ để tải khác nhau InnerFrag s. Tóm lại, tôi muốn gọi getChildFragmentManager() trong OuterFrag, khi được thêm theo chương trình (động).

+0

Bạn có làm việc này? Câu hỏi của tôi là khi nào bạn thêm 'InnerFrag' để nó phù hợp với vòng đời của' OuterFrag'? – StuStirling

Trả lời

45

In conclusion, I want to reference OuterFrag in MainActivity always. And I want OuterFrag act as a placeholder to load different InnerFrags. In short, I want to call getChildFragmentManager() in OuterFrag, when it is added programmatically (dynamically).

Nếu bạn muốn điều này thì chắc bạn OuterFrag có một bố cục container như nội dung của nó và thêm bất cứ điều gì InnerFrag để chứa đó. Các tập tin bố trí cho các OuterFrag sẽ là:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/fragContainer" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
/> 

Tất nhiên bạn có thể có quan điểm khác trong cách bố trí cho OuterFrag nếu bạn muốn điều đó. Sau đó, phương pháp addInnerFrag của bạn sẽ là:

public void addInnerFrag() { 
     getChildFragmentManager().beginTransaction().add(R.id.fragContainer, new InnerFrag()).commit(); 
     getChildFragmentManager().executePendingTransactions(); 
} 

Mã cho thêm OuterFrag đến hoạt động chính vẫn có giá trị.

+1

nó hoạt động hoàn hảo! Cảm ơn rất nhiều! – midnite

+0

Hi @Luksprog tôi đã làm theo các phương pháp trên và các mảnh bên trong được thêm vào OuterFragment. Nhưng OuterFragment không thay thế nội dung. Nó được thêm vào dưới dạng xem và nội dung trước đó trong OuterFragment cũng hiển thị. Tôi cũng đã thử sử dụng ** beginTransaction(). Thay thế ** nhưng không có thay đổi trong op. Xin hãy giúp tôi ................... –

+1

@ KK_07k11A0585 Vui lòng đăng câu hỏi mới cung cấp thêm chi tiết về vấn đề của bạn. Hãy nhớ rằng một giao dịch phân đoạn sẽ không thay thế các khung nhìn đã có trong bố trí nơi mà đoạn sẽ được thêm vào. Nếu bạn muốn thay thế điều đó thì hãy đặt những khung nhìn ban đầu đó vào một đoạn khác. – Luksprog

0

Nếu bạn muốn gọi addInnerFrag() trong mã OuterFrag.java của bạn, bạn có thể làm điều đó như thế này:

OuterFrag.java:

@Override 
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    addInnerFrag(); 
} 
Các vấn đề liên quan