<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
當快速點選切換不同的Fragment的時候部分手機的app竟然掛了,
報出了下面的錯誤 Fragment already added
java.lang.IllegalStateException: Fragment already added: xxxxFragment
上網找了很多,大致得到的原因是當快速雙擊呼叫FragmentTransaction.add()方法新增fragmentA,而fragmentA不是每次單獨生成的,就會引起這個異常。
上面的內容是網上的解釋,不過我認為是因為同一個Fragment被add兩次導致的錯誤,但是奇怪的是我在載入這個Fragment的時候已經做了是否add的判斷,為什麼還會有這個問題呢。
private void addFragment(FragmentManager fm, Fragment fragment ) { Log.i( "addFragment", "### " + fragment.getId() + " " + fragment.isAdded() + " " + fragment.isHidden() ); if (!fragment.isAdded() ) { FragmentTransaction ft = fm.beginTransaction(); fm.executePendingTransactions(); ft.add( R.id.main_content, fragment ); ft.commitAllowingStateLoss(); }
通過列印結果發現,第一次切換到FragmentA的時候,FragmentA明明已經add了,但是isAdded()依然顯示false
addFragment: ###1 2131755357 false true
addFragment: ###2 2131755357 false true
addFragment: ###3 2131755357 false true
addFragment: ###4 2131755357 false true
第二次切換到相同FragmentA的時候isAdded()就顯示為true了
addFragment: ###1 2131755357 true true
addFragment: ###2 2131755357 true true
addFragment: ###3 2131755357 true true
addFragment: ###4 2131755357 true true
在不斷快速切換不同的Fragment的時候,isAdded()偶爾會顯示false,就因為isAdded()顯示了false,那麼 ft.add( R.id.main_content, fragment )就會再次執行一次,就會報錯,說明通過isAdded()這個方法判斷Fragment是否被add可能並不準確。
解決方法就是每次add的時候加上一個tag,然後不僅要通過isAdded()判斷Fragment是否add,還要通過FragmentManager.findFragmentByTag(tag)獲取Fragment,然後判斷此Fragment是否為null。
case R.id.home_tab_a: hideAllFragment( fm ); addFragment( fm, fragmentA, "A" ); showFragment( fm, fragmentA ); break; case R.id.home_tab_b: hideAllFragment( fm ); addFragment( fm, fragmentB, "B" ); showFragment( fm, fragmentB ); break; case R.id.home_tab_c: hideAllFragment( fm ); addFragment( fm, fragmentC, "C" ); showFragment( fm, fragmentC ); break;
影藏所有的Fragment
private void hideAllFragment(FragmentManager fm) { FragmentTransaction ft = fm.beginTransaction(); if (!shijianFragment.isHidden()) ft.hide( fragmentA ); if (!riliFragment.isHidden()) ft.hide( fragmentB ); if (!gongjuFragment.isHidden()) { ft.hide( fragmentC ); } ft.commitAllowingStateLoss(); }
通過isAdded()判斷Fragment是否add,同時通過tag獲取Fragment,判斷Fragment是否為空,雙重判斷
private void addFragment(FragmentManager fm, Fragment fragment, String tag) { if (!fragment.isAdded()&&null == fm.findFragmentByTag( tag )) { FragmentTransaction ft = fm.beginTransaction(); fm.executePendingTransactions(); ft.add( R.id.main_content, fragment, tag ); ft.commitAllowingStateLoss(); } }
顯示Fragment
private void showFragment(FragmentManager fm, Fragment fragment) { FragmentTransaction ft = fm.beginTransaction(); ft.show( fragment ); ft.commitAllowingStateLoss(); }
10-15 15:52:00.094 3808 3808 E AndroidRuntime: FATAL EXCEPTION: main
10-15 15:52:00.094 3808 3808 E AndroidRuntime: Process: com.xxxx.xxx, PID: 3808
10-15 15:52:00.094 3808 3808 E AndroidRuntime: java.lang.IllegalStateException: Fragment already added
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.fragment.app.Fragment.setInitialSavedState(Fragment.java:679)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.viewpager2.adapter.FragmentStateAdapter.ensureFragment(FragmentStateAdapter.java:269)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.viewpager2.adapter.FragmentStateAdapter.onBindViewHolder(FragmentStateAdapter.java:175)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.viewpager2.adapter.FragmentStateAdapter.onBindViewHolder(FragmentStateAdapter.java:67)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.recyclerview.widget.RecyclerViewA d a p t e r . o n B i n d V i e w H o l d e r ( R e c y c l e r V i e w . j a v a : 7065 ) 10 − 1515 : 52 : 00.09438083808 E A n d r o i d R u n t i m e : a t a n d r o i d x . r e c y c l e r v i e w . w i d g e t . R e c y c l e r V i e w Adapter.onBindViewHolder(RecyclerView.java:7065) 10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.recyclerview.widget.RecyclerViewAdapter.onBindViewHolder(RecyclerView.java:7065)10−1515:52:00.09438083808EAndroidRuntime:atandroidx.recyclerview.widget.RecyclerViewAdapter.bindViewHolder(RecyclerView.java:7107)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.recyclerview.widget.RecyclerViewR e c y c l e r . t r y B i n d V i e w H o l d e r B y D e a d l i n e ( R e c y c l e r V i e w . j a v a : 6012 ) 10 − 1515 : 52 : 00.09438083808 E A n d r o i d R u n t i m e : a t a n d r o i d x . r e c y c l e r v i e w . w i d g e t . R e c y c l e r V i e w Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012) 10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.recyclerview.widget.RecyclerViewRecycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)10−1515:52:00.09438083808EAndroidRuntime:atandroidx.recyclerview.widget.RecyclerViewRecycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:755)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at android.os.Looper.loop(Looper.java:154)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6141)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:913)
10-15 15:52:00.094 3808 3808 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:803)
報錯AndroidRuntime: at androidx.fragment.app.Fragment.setInitialSavedState(Fragment.java:679)
這個錯誤是我從 fragment A 切換到 fragment B ,fragment B再切換到 fragment C 中,再切換到 fragment B中, fragment B 裡面 使用了ViewPager2 + FragmentStateAdapter + RadioButton切換主題,問題就出在我使用的ViewPager2 + FragmentStateAdapter這裡。
每次我在多個fragmentA,B,C之間多次切換後,切換到fragment B,點選 radioButton 通知ViewPager2 切換 fragment的主題時,使用方法viewPager2.setCurrentItem(index);,就報上面的錯誤。
我在想,是否是滑動效果的問題,於是 用viewPager2.setCurrentItem(index,false);然後,由於viewpager2 裡面的fragment 裡面有recycleviewer ,把viewpager2 的寬高 固定 ,問題解決。
1、viewPager2.setCurrentItem(index)改成viewPager2.setCurrentItem(index,false);
2、viewPager2 在佈局檔案裡面把寬高 固定。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45