17

我正在尝试以一种非常简单的方式使用 Android 片段,类似于 Android 开发者网站上的教程。

我有一个带有以下代码的活动(MediaInfoActivity):

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);
    }

}

这是 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>

最后是 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);
    }

}

这是我的问题:MediaInfoFragment 的 onCreateView() 方法中传递的容器为空。据我了解,这应该只适用于非 UI 片段。但是,我的 Fragment 有一个 UI,当我启动 MediaInfoActivity 时,它在屏幕上显示为 OK。它会导致问题,因为没有应用在片段的 xml 布局文件中声明的样式。

这是我的日志:

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

我在这里遗漏了什么明显的东西吗?

4

2 回答 2

3

你只需要在你的片段中创建一个像下面这样的充气器。

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;
}

我希望它会根据您的问题起作用。

于 2015-10-30T12:39:05.697 回答
2

I am not sure since I don't have the code of the SDK in front of me but I think that the life-cycle of calling Fragment "onCreateView" function is different between the two cases: 1. Static settings of fragment in layout 2. Loading pragmatically with FragmentManager.

In the first case the debugger get into Fragment.onCreateView() method immediately upon adding the content view to the parent activity as part of onCreate() code:

When calling: setContentView(R.layout.some_layoue); You will see the debugger get into Fragment.onCreateView() before going to next line

In the second case the Fragment.onCreateView() is being invoked only after the onCreate() of the activity is finished.

This looks like design bug for me but possibly as design feature. Anyway the container is null when adding fragment statically because the related object was not yet created.

In fact the difference between the two situations is much deeper. In the case of static fragments toggling between fragments will not create the view hierarchy correctly.

For example if you will add button-A to fragment A and button-B to Fragment-B and toggle the fragments with a code looks like this (highlighting only the relevant code):

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();


    }
}

You will see that in the case of static fragments the buttons from both fragments are presented although turning on and off. If however fragments are added programatically the toggle works fine and view hierarchy is cleaned and show only button from relevant fragment.

This is based of my experience with version 4.4.2

于 2014-07-22T10:20:31.933 回答