Android 一种关于解决 No view found for id xxxx for fragment xxxx 问题的方案 - Go语言中文社区

Android 一种关于解决 No view found for id xxxx for fragment xxxx 问题的方案


 一、问题描述

       因为一直在参加比赛开发一款 APP ,然后今天在测试的时候发现了一个问题,即当打开进入 APP 后,走过以下路径

近期记录——》班级——》打开班级详情——》个人中心——》当前课堂 时(下面的动图为已修复后的路径演示),出现了软件闪退的情况。

       经过查找,找到了软件崩溃时的错误记录如下:

2019-02-25 14:49:56.735 12007-12015/? E/art: Failed sending reply to debugger: Broken pipe
2019-02-25 14:49:57.580 12007-12042/? E/OpenGLRenderer: hwui_debug::CanvasContext createSurface sur=0x0, isValid =0
2019-02-25 14:49:58.807 12007-12042/com.example.smartclass E/OpenGLRenderer: hwui_debug::CanvasContext createSurface sur=0x0, isValid =0
2019-02-25 14:50:03.367 12007-12042/com.example.smartclass E/OpenGLRenderer: hwui_debug::CanvasContext createSurface sur=0x0, isValid =0
2019-02-25 14:50:10.292 12007-12007/com.example.smartclass E/FragmentManager: No view found for id 0x7f0900b4 (com.example.smartclass:id/recentRecordStatisticsViewPager) for fragment RecentOverallStudentStatusRankingsFragment{8a0f94c #2 id=0x7f0900b4 android:switcher:2131296436:0}
2019-02-25 14:50:10.292 12007-12007/com.example.smartclass E/FragmentManager: Activity state:
2019-02-25 14:50:10.350 12007-12007/com.example.smartclass E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.smartclass, PID: 12007
    java.lang.IllegalArgumentException: No view found for id 0x7f0900b4 (com.example.smartclass:id/recentRecordStatisticsViewPager) for fragment RecentOverallStudentStatusRankingsFragment{8a0f94c #2 id=0x7f0900b4 android:switcher:2131296436:0}
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1454)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
        at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3269)
        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
        at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:2466)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1483)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
        at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3269)
        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
        at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:2466)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1483)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
        at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
        at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
        at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
        at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2243)
        at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:654)
        at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:146)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1244)
        at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:669)
        at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:631)
        at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:612)
        at android.support.design.widget.TabLayout$ViewPagerOnTabSelectedListener.onTabSelected(TabLayout.java:2831)
        at android.support.design.widget.TabLayout.dispatchTabSelected(TabLayout.java:1608)
        at android.support.design.widget.TabLayout.selectTab(TabLayout.java:1601)
        at android.support.design.widget.TabLayout.selectTab(TabLayout.java:1569)
        at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1874)
        at android.support.design.widget.TabLayout$TabView.performClick(TabLayout.java:2059)
        at android.view.View$PerformClick.run(View.java:22695)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:185)
        at android.app.ActivityThread.main(ActivityThread.java:6615)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:916)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:806)

二、问题分析

       通过分析报错,我们可以看到崩溃的原因是

No view found for id 0x7f0900b4 (com.example.smartclass:id/recentRecordStatisticsViewPager) for fragment RecentOverallStudentStatusRankingsFragment{8a0f94c #2 id=0x7f0900b4 android:switcher:2131296436:0}

也就是说,在 fragment 中查找不到 id 为 recentRecordStatisticsViewPager 的组件。

       但是为什么会出现这种情况呢,我进行了一下软件的整体结构分析,这个 APP 打开后即用 TabLayout + ViewPager 实现了一个底部导航栏,然后在近期记录这个子页面中,又再次使用了 TabLayout + ViewPager 实现了一个顶部导航栏,紧接着在班级这个子页面下,使用 ExpandableList 实现了一个可伸缩的列表,之后在列表的子项目中又再次使用 TabLayout + ViewPager 实现了两个小的分标签页面。

       从整体的结构入手,排查代码同时上网查找资料,网上提示的最多的一种是在 Fragment 中嵌套的 Fragment 如果想要获取 FragmentManager 需要使用 fragment.getChildFragmentManager() 而不是 fragment.getFragmentManager(),但是这种原因我提前已经考虑过了,所以问题不在这里。

       第二个可能性是出在 ViewPager 上面,进行资料的查找后,发现 ViewPager 工作机制是这样的:

在使用 ViewPager 与 Fragment 的时候,ViewPager 会自动缓存一页内的数据,如下图:

       所以当我们当前处在 页面2 的时候,页面1 和 页面3 的 View 实际上已经创建好了,所以在我们拖动的时候是可以看见他们的界面的。但是当我们的页面处在 页面1 的时候,页面3 实际上就已经销毁了,直到跳转到 页面2 的时候,页面3 才会创建 View 。也就是说,每次他都是只缓存相邻的一个页面的,而当前页面的相邻的第二个开始的页面都会被销毁。

       这样我们也就找到了问题所在,即当我们从 近期记录 跳转到 个人中心 的页面后,近期记录 的页面其实就已经被销毁了,所以才会发生 “ 在 fragment 中查找不到 id 为 recentRecordStatisticsViewPager 的组件 ” 这样的问题。

三、解决方法

       找到了问题所在,想要解决问题就很简单了,只需要将 ViewPager 的缓存页面数增加到两页,那么当我们访问 个人中心 页面的时候 近期记录 页面就不会被销毁了,这样当我们再点击回去的时候,就可以正常的进行访问了,解决的代码如下:

ViewPager.setOffscreenPageLimit(2);

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_40697071/article/details/87923655
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-27 23:20:40
  • 阅读 ( 752 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢