【问题标题】:Android No View Found for Fragment after Orientation ChangeAndroid 在方向更改后找不到片段的视图
【发布时间】:2014-08-01 12:55:01
【问题描述】:

当我的设备方向改变时出现错误。在方向改变之前一切正常。

我有一个片段 (TrapCheckContainerFragment),其中包含一个用于容纳另一个片段 (TrapCheckFragment) 的 FrameLayout。 TrapCheckFragment 在 TrapCheckContainerFragment 的 onCreateView 方法中创建,并使用 FragmentTransaction 放入 FrameLayout。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_trap_check_container, container, false);

    TrapCheckFragment fragment = new TrapCheckFragment();

    ReplaceFragment(R.id.trapCheckHolder, fragment, false, feature.trapUniqueID.toString());

    return rootView;
}

private void ReplaceFragment(int idToReplace, Fragment newFragment, boolean addToBackStack, String tag){

    FragmentTransaction transaction = getFragmentManager().beginTransaction();

    transaction.replace(idToReplace, newFragment, tag);

    if(addToBackStack){
        transaction.addToBackStack(null);
    }

    transaction.commit();
}

这一切正常,直到我旋转设备。据我所知,我的代码都没有被调用,但由于某种原因,FragmentManager 无法找到名为 trapCheckHolder 的视图,它是用于保存子片段的 FrameLayout。如果我删除对 ReplaceFragment 的调用,那么当我旋转设备时一切正常。

logcat 消息:

 FATAL EXCEPTION: main
 Process: com.redacted.appname, PID: 29396
 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.redacted.appname/com.redacted.appname.activities.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f0a0042 (com.redacted.appname:id/trapCheckHolder) for fragment TrapCheckFragment{64fa6b18 #4 id=0x7f0a0042 10236}
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3724)
    at android.app.ActivityThread.access$900(ActivityThread.java:135)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1202)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5001)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
 Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f0a0042 (com.redacted.appname:id/trapCheckHolder) for fragment TrapCheckFragment{64fa6b18 #4 id=0x7f0a0042 10236}
    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:882)
    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
    at android.app.BackStackRecord.run(BackStackRecord.java:684)
    at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
    at android.app.Activity.performStart(Activity.java:5240)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2157)
    ... 10 more

我已经尝试将 setRetainInstance 设置为 true 和 false 对于 this 和 parent Fragment 但这没有任何区别。我在这里所做的事情有什么明显的问题吗?有没有办法强制创建一个新的 TrapCheckFragment 而不是试图显示似乎导致此问题的旧 TrapCheckFragment?

如果需要,我可以提供有关任何代码或错误的更多信息。

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    onCreateViewMethod 似乎引起了问题;如果容器为空,它必须返回空:

    执行类似的操作来检查 null 并重新创建视图:

     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            if (rootView == null) {
                // Inflate the layout for this fragment 
                rootView = inflater.inflate(R.layout.fragment_a, container, false);
    
            } else { 
                // Do not inflate the layout again. 
                // The returned View of onCreateView will be added into the fragment. 
                // However it is not allowed to be added twice even if the parent is same. 
                // So we must remove rootView from the existing parent view group 
                // (it will be added back). 
                ((ViewGroup)rootView.getParent()).removeView(rootView);
            } 
            return rootView;
    

    请检查一下,如果它有效,请告诉我。

    【讨论】:

    • 在这个例子中我应该如何获得 _rootView?我尝试存储创建的 rootView 并调用 getView() 但第一个从 getParent() 返回 null ,第二个在方向更改时为 null。
    • rootView 只是一个类变量,例如:View rootView; 第一次创建片段时它始终为空。
    • 似乎 rootView.getParent() 正在返回 null。我在调试时遇到了麻烦,因为如果附加了调试器并且在设备轮换发生后没有遇到任何断点,应用程序会崩溃而没有错误消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多