在我的应用程序中,我切换到一个主要活动并使用新的NavigationDrawer.所有内容都包含在片段中.
One Fragment(搜索用户)包含两个选项卡(按名称搜索,按标准搜索),使用Android设计网站中的导航模式“横向导航”:它有一个带有FragmentStatePagerAdapter的VIEwPager.
| Main Activity | | Main Activity |------------------- -------------------| Search Fragment | | Search Fragment || >Tab 1< | Tab 2 | | Tab 1 | >Tab 2< || VIEw Pager | | VIEw Pager || Fragment 1 | | Fragment 2 |
我希望两个选项卡都使用相同的 *** 作栏(选项)菜单:搜索 *** 作.
但只有活跃的片段才会对它做出反应.
我尝试过不同的方法,最烦人的是我无法直接从视图分页器中获取当前片段(不依赖于非API实现细节).
途径
我现在使用Localbroadcast来通知片段已经点击了搜索.每个片段在onResume中注册一个小的Wrapper-Receiver(并在onPause中删除它),它将onReceive转发给片段本身(下面显示的方法).
我重写setMenuVisibility,它是FragmentStatePagerAdpater在Fragments上调用的回调,以了解哪个是活动片段.
只有菜单集可见的片段才会对广播做出反应.
Actionbar Tab -> VIEwPager -> VIEwPagerAdapter -> Fragment.setMenuVisibilityActionbar Menu Action -> broadcast -> ... -> broadcastReceiver -> Fragments
两个片段都会触发片段事务以显示搜索结果并将其添加到后台堆栈.
问题
片段事务通常起作用,但是当我旋转设备然后按搜索时,我得到一个IllegalStateException(在onSaveInstanceState之后无法提交).
@OverrIDe public voID onReceive(Context context,Intent intent) { if (m_menuVisible) { final String s = ((TextVIEw) getVIEw().findVIEwByID(R.ID.search_text)).getText().toString(); SearchResultsFragment f = new UserSearchResultsFragment(); Bundle b = new Bundle(); b.putString(SearchResultsFragment.EXTRA_SEARCHname,s); f.setArguments(b); FragmentTransaction transaction = getSherlockActivity().getSupportFragmentManager().beginTransaction(); transaction.replace(R.ID.fragment_container_frame,f).addToBackStack(null).commit(); // <<< CRASH } }
我试图将提交更改为commitAllowingStateLoss,但随后我得到一个IllegalStateException,其中“Activity已被销毁”.
你知道这里出了什么问题吗?我不知所措……
附加代码:
MainActivitIEs onCreate(基于NavigationDrawer示例)和selectItem
@OverrIDeprotected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestwindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentVIEw(R.layout.fragment_container_layout); setupDrawer(); // Sets up the drawer layout,adapter,etc. if (savedInstanceState == null) { selectItem(0); // Selects and adds the fragment(s) for the position } // Other setup stuff}private voID selectItem(int position) { // update the main content by replacing fragments Fragment f = null; switch (position) { case 0: f = ... break; case 1: ... default: throw new IllegalArgumentException("Could not find right fragment"); } f.setRetainInstance(true); m_drawerList.setItemChecked(position,true); setTitle(mDrawerTitles.get(position).TitleRes); // HIDe any progress bar that might be visible in the actionbar setProgressbarIndeterminateVisibility(false); // When we select something from the navigation drawer,the back stack is discarded final FragmentManager fm = getSupportFragmentManager(); fm.popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE); fm.beginTransaction().replace(R.ID.fragment_container_frame,f).commit(); // update selected item and Title,then close the drawer m_drawerLayout.closeDrawer(GravityCompat.START); }
故障选项卡片段中的FragmentStatePagerAdapter:
protected class TabPagerAdapter extends FragmentStatePagerAdapter { private List<String> m_fragmentTags = new ArrayList<String>(); public TabPagerAdapter(FragmentManager fm) { super(fm); } public voID addFragments(List<String> List) { VIEwPager pager = (VIEwPager) getVIEw().findVIEwByID(R.ID.vIEwpager); startUpdate(pager); for (String tag : List) { m_fragmentTags.add(tag); } finishUpdate(pager); notifyDataSetChanged(); } public voID addFragment(String tag) { addFragments(Collections.singletonList(tag)); } @OverrIDe public Fragment getItem(int pos) { // CreateFragmentForTag: RetrIEves the classes,instantiates the fragment // Does not do retainInstance or any transaction there. return createFragmentForTag(m_fragmentTags.get(pos)); } @OverrIDe public int getCount() { return m_fragmentTags.size(); }}
该项目的精简版仅包含必需品,发布于https://docs.google.com/file/d/0ByjUMh5UybW7cnB4a0NQeUlYM0E/edit?usp=sharing
重现如下:启动,您会看到两个选项卡.选择其中一个并单击Actionbar中的搜索 – >片段交易有效.使用返回键,旋转设备并重复 – >崩溃!
[在赏金结束或发现错误后,该文件可能无法访问.]
编辑:
(1)澄清onReceive生活在片段的上下文中
(2)增加了主要活动的代码
第一个线索是你只在旋转后崩溃,并且你有setRetainInstance(true).首先,尝试将其设置为false.即使这可以防止崩溃,你仍然需要谨慎.它可能指向一些其他错误,你现在通过不保留你的片段实例来掩盖它.
有没有特别的原因你首先设置了setRetainInstance(true)?
至于为什么你开始看到崩溃,我仍然不能指出这个问题.我怀疑旋转后调用了错误的onReceive – 但这只是在黑暗中拍摄的.
如果您可以创建应用程序的框架并在某处发布代码,我可以查看它.我知道你已经总结了如何“转发”onReceive(),但如果做得不对,就有可能在那里引入BUG.
如果这是不可能的,这就是我的建议 – 将日志语句放在Activity,Fragments和onReceive()的主要生命周期方法中.这会告诉你发生的确切顺序.
总结以上是内存溢出为你收集整理的android – 循环后,片段事务给出了IllegalStateException全部内容,希望文章能够帮你解决android – 循环后,片段事务给出了IllegalStateException所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)