2013-06-02 20 views
14

Tôi đang cố gắng sử dụng các đoạn Android theo cách rất đơn giản, tương tự như hướng dẫn trên trang web dành cho nhà phát triển Android.Android Fragment được cung cấp một vùng chứa rỗng trong onCreateView()

Tôi có một hoạt động (MediaInfoActivity) với đoạn mã sau:

public class MediaInfoActivity extends FragmentActivity { 
    private final String TAG = "MediaInfoActivity"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Log.i(TAG, "onCreate()"); 
     setContentView(R.layout.media_info_activity_layout); 
    } 

} 

Đây là mã cho file media_info_activity_layout.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <fragment class="com.hawkforce.test.MediaInfoFragment" 
      android:id="@+id/mediaInfoFragment" 
      android:layout_weight="1" 
      android:layout_width="match_parent" 
      android:layout_height="0dp" /> 

    <FrameLayout android:id="@+id/mediaPlayerBarPanel" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" > 

    <fragment class="com.hawkforce.test.MediaPlayerBarFragment" 
       android:id="@+id/mediaPlayerBar" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" /> 

    </FrameLayout> 

Và cuối cùng ở đây là mã cho MediaInfoFragment:

public class MediaInfoFragment extends Fragment { 
    private final static String TAG = "MediaInfoFragment"; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Log.i(TAG, "onCreate()"); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     Log.i(TAG, "onCreateView()"); 
     if (container == null) { 
      Log.i(TAG, "onCreateView(): container = null"); 
     } 

     return inflater.inflate(R.layout.media_info_fragment_layout, container, false); 
    } 

} 

Đây là vấn đề của tôi: vùng chứa được truyền trong phương thức onCreateView() của MediaInfoFragment là null. Như tôi đã hiểu, điều này chỉ nên xảy ra đối với các mảnh không phải UI. Tuy nhiên, Fragment của tôi có một giao diện người dùng, được hiển thị OK trên màn hình khi tôi khởi chạy MediaInfoActivity. Nó gây ra vấn đề vì không có kiểu được khai báo trong tệp sơ đồ bố trí xml của đoạn được áp dụng.

Đây là Log của tôi:

I/MediaInfoActivity: onCreate() 
I/MediaInfoFragment: onCreate() 
I/MediaInfoFragment: onCreateView() 
I/MediaInfoFragment: onCreateView(): container = null 

Am tôi thiếu bất cứ điều gì rõ ràng ở đây?

+0

Bạn sử dụng sai nghĩa là nó không được đính kèm vào vùng chứa. –

+0

Bạn có nghĩa là trong inflater, phải không? Tôi đã thay đổi nó thành sự thật nhưng không có thay đổi. Cộng với dòng này: 'onCreateView(): container = null' được hiển thị trước cuộc gọi đến inflater. Vấn đề của tôi thực sự là Android vượt qua null như một đối số thứ hai cho onCreateView() và tôi không hiểu nó xuất phát từ đâu. – HawkForce

+0

- http://stackoverflow.com/questions/27306805/android-fragment-oncreateview-container-is-null - http://stackoverflow.com/questions/24589202/android-fragments-container-variable-in- oncreateview-is-null – pRaNaY

Trả lời

2

Tôi không chắc chắn vì tôi không có mã của SDK trước mặt tôi nhưng tôi nghĩ rằng vòng đời gọi Fragment "onCreateView" chức năng là khác nhau giữa hai trường hợp: 1. Cài đặt tĩnh của đoạn trong bố cục 2. Tải thực tế với FragmentManager.

Trong trường hợp đầu tiên trên debugger nhận được vào Fragment.onCreateView() phương pháp ngay khi thêm xem nội dung để hoạt động cha mẹ như một phần của onCreate() mã:

Khi gọi: setContentView (R.layout.some_layoue); Bạn sẽ thấy trình gỡ lỗi nhận được vào Fragment.onCreateView() trước khi đi dòng tiếp theo

Trong trường hợp thứ hai Fragment.onCreateView() đang được gọi chỉ sau khi onCreate() của hoạt động đã kết thúc.

Điều này trông giống như lỗi thiết kế cho tôi nhưng có thể là tính năng thiết kế. Dù sao vùng chứa là rỗng khi thêm phân đoạn tĩnh bởi vì đối tượng liên quan chưa được tạo.

Thực tế, sự khác biệt giữa hai tình huống sâu hơn nhiều. Trong trường hợp các phân đoạn tĩnh chuyển đổi giữa các đoạn sẽ không tạo ra phân cấp khung nhìn chính xác.

Ví dụ, nếu bạn sẽ thêm nút A đến đoạn A và nút B để fragment-B và chuyển đổi các mảnh vỡ với một mã trông như thế này (làm nổi bật chỉ mã có liên quan):

public void turnOnFragment() { 
    FragmentManager manager = getFragmentManager(); 
    if (manager != null) { 
     manager.beginTransaction() 
       .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out) 
       .attach(this) 
       .commit(); 
    } 
} 



public void turnOffFragment() { 
    FragmentManager manager = getFragmentManager(); 
    if (manager != null) { 
     manager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 
     manager.beginTransaction() 
       .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out) 
       .detach(this) 
       .commit(); 


    } 
} 

Bạn sẽ thấy rằng trong trường hợp các đoạn tĩnh, các nút từ cả hai đoạn được trình bày mặc dù bật và tắt. Tuy nhiên, nếu các mảnh vỡ được thêm vào theo chương trình, công tắc bật tắt hoạt động tốt và phân cấp xem được làm sạch và chỉ hiển thị nút từ đoạn có liên quan.

Điều này dựa trên kinh nghiệm của tôi với phiên bản 4.4.2

3

Bạn chỉ cần tạo một inflater như dưới đây trong đoạn của bạn.

View rootView; 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    if (rootView == null) { 
     rootView = inflater.inflate(R.layout.activity_my_cart, null); 
    } else { 
     ((ViewGroup) container.getParent()).removeView(rootView); 
    } 
    return rootView; 
} 

Tôi hy vọng nó sẽ hoạt động theo câu hỏi của bạn.

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