书籍页面需要显示轮播图组件,上网找了个现成封装好的,感谢这个哥们儿 http://blog.csdn.net/stevenhu_223/article/details/45577781
down下来用到看书中,是封装在fragment里的,我是在BookView中动态调用的,调用方式:
LayoutInflater lif = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View lubotuView = lif.inflate(R.layout.lunbotu, null);
CycleViewPager cycleViewPager = (CycleViewPager) ((Activity) context).getFragmentManager().findFragmentById(R.id.lunbotuCycle);
LinearLayout lunbotuLL = (LinearLayout) lubotuView.findViewById(R.id.lunbotuLL);
addView(lubotuView);
好使,成功调用。
但是在翻页过程中,第二次翻到此页就崩溃了,崩溃信息:
E/AndroidRuntime(6462): android.view.InflateException: Binary XML file line #8: Error inflating class fragment
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719)
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
10-14 06:51:37.676: E/AndroidRuntime(6462): at com.sea.testRatingBar.bookView.loadCarouselNode(bookView.java:132)
10-14 06:51:37.676: E/AndroidRuntime(6462): at com.sea.testRatingBar.bookView.loadElement(bookView.java:63)
10-14 06:51:37.676: E/AndroidRuntime(6462): at com.sea.testRatingBar.bookView.<init>(bookView.java:50)
10-14 06:51:37.676: E/AndroidRuntime(6462): at com.sea.testRatingBar.BookPageAdapter.getView(BookPageAdapter.java:55)
10-14 06:51:37.676: E/AndroidRuntime(6462): at com.aphidmobile.flip.FlipViewController.viewFromAdapter(FlipViewController.java:478)
10-14 06:51:37.676: E/AndroidRuntime(6462): at com.aphidmobile.flip.FlipViewController.flippedToView(FlipViewController.java:545)
10-14 06:51:37.676: E/AndroidRuntime(6462): at com.aphidmobile.flip.FlipViewController$2.run(FlipViewController.java:519)
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.os.Handler.handleCallback(Handler.java:733)
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.os.Handler.dispatchMessage(Handler.java:95)
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.os.Looper.loop(Looper.java:136)
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.app.ActivityThread.main(ActivityThread.java:5479)
10-14 06:51:37.676: E/AndroidRuntime(6462): at java.lang.reflect.Method.invokeNative(Native Method)
10-14 06:51:37.676: E/AndroidRuntime(6462): at java.lang.reflect.Method.invoke(Method.java:515)
10-14 06:51:37.676: E/AndroidRuntime(6462): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
10-14 06:51:37.676: E/AndroidRuntime(6462): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
10-14 06:51:37.676: E/AndroidRuntime(6462): at dalvik.system.NativeStart.main(Native Method)
10-14 06:51:37.676: E/AndroidRuntime(6462): Caused by: java.lang.IllegalArgumentException: Binary XML file line #8: Duplicate id 0x7f09000a, tag null, or parent id 0x7f090009 with another fragment for cn.androiddevelop.cycleviewpager.lib.CycleViewPager
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.app.Activity.onCreateView(Activity.java:5002)
10-14 06:51:37.676: E/AndroidRuntime(6462): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695)
10-14 06:51:37.676: E/AndroidRuntime(6462): ... 20 more
一看就是fragment重复调用,造成了这个错误
解决方案1:所以用完了得remove掉,在CycleViewPager这个fragment中添加个ondestroy方法,当ondestroy销毁时remove此frg
public void onDestroyView() {
super.onDestroyView();
FragmentManager fm = getActivity().getSupportFragmentManager();
Fragment fragment = (fm.findFragmentById(R.id.cyclepic));
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();
}
测试,不好使,Sh*t
解决方案2:优化oncreate生命周期,如果之前创建过,就删除,老一套:
<span style="white-space:pre"> </span>public CycleViewPager() {
}
private static View rootView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// View view =
// LayoutInflater.from(getActivity()).inflate(R.layout.view_cycle_viewpager_contet,
// null);
if (rootView != null) {
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null)
parent.removeView(rootView);
}
try {
rootView = LayoutInflater.from(getActivity()).inflate(R.layout.view_cycle_viewpager_contet, null);
} catch (InflateException e) {
}
测试,不好使,double Sh*t
解决方案3:这些都不好使,那还试试那个remove的,经过了漫长的逻辑方面的探索,终于锁定在adapter中,移除所有view之前remove
int childCount0 = viewHolder.ll.getChildCount();
for (int i = 0; i < childCount0; i++) {
View v = viewHolder.ll.getChildAt(i);
BookView bv = (BookView) v;
int bvChildCount = bv.getChildCount();
for (int j = 0; j < bvChildCount; j++) {
View bvv = bv.getChildAt(j);
if(bvv instanceof LinearLayout){
if(bvv.getId() == R.id.lunbotuLL){
FragmentManager fm = ((Activity) c).getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.lunbotuCycle);
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();
}
}
}
}
viewHolder.ll.removeAllViews();
测试,还tm不好使,triple Sh*t
解决方法4:思考了一下,逻辑肯定是对的,还是报错的话,是不是ft.commit这个方法不执行啊,
上网搜到了一篇文章http://blog.csdn.net/picasso_l/article/details/50994143 ,按照文章说法,添加了一个
fm.executePendingTransactions();
即 立即执行 !
测试,好使!
贴一下http://blog.csdn.net/picasso_l/article/details/50994143 这个博客的内容,当做记录,对博主表示感谢:
FragmentTransaction是异步的,commit()仅是相当于把操作加入到FragmentManager的队列,然后FragmentManager会在某一个时刻来执行,并不是立即执行。所以,真正开始执行commit()时,如果Activity的生命周期发生了变化,比如走到了onPause,或者走到了onStop,或者onDestroy都走完了,那么就会报出IllegalStateException。
这个地方确实是很坑的,我在做一个功能,需要从FragmentA跳转到FragmentB,然后调用FragmentB的刷新方法,那我的思路是从FragmentA和B的MainActivity中将A隐藏,将B显示,然后调用刷新。
于是我先将A隐藏B显示
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">private void switchFragment(Fragment newFragment) {
FragmentManager fm = getSupportFragmentManager()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
FragmentTransaction transaction = fm<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.beginTransaction</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
LogCat<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.i</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"newFragment isAdded="</span> + newFragment<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isAdded</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
if (newFragment<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isAdded</span>()) {
transaction<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.hide</span>(mCurrentFragment)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.show</span>(newFragment)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.commitAllowingStateLoss</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
} else {
transaction<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.hide</span>(mCurrentFragment)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.add</span>(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.id</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.main</span>_content, newFragment)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.commitAllowingStateLoss</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}
mCurrentFragment = newFragment<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>
然后,再switchFragment之后调用FragmentB的刷新功能,但是问题出现了,发现FragmentB里面的一些空间没有初始化,打了log之后发现,初始化在我的初始化在我的刷新功能后面执行,查了资料发现,FragmentTransaction的commit方法是异步的,难怪~
解决方法:executePendingTransactions
在用FragmentTransaction.commit()方法提交FragmentTransaction对象后,会在进程的主线程中,用异步的方式来执行。如果想要立即执行这个等待中的操作,就要调用这个方法(只能在主线程中调用)。要注意的是,所有的回调和相关的行为都会在这个调用中被执行完成,因此要仔细确认这个方法的调用位置。
于是我重写switchFragment方法
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">FragmentManager fm = getSupportFragmentManager()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
FragmentTransaction transaction = fm<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.beginTransaction</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
if (fragment<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isAdded</span>()) {
transaction<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.hide</span>(mCurrentFragment)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.show</span>(fragment)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.commitAllowingStateLoss</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
} else {
transaction<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.hide</span>(mCurrentFragment)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.add</span>(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.id</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.main</span>_content, fragment)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.commitAllowingStateLoss</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}
mCurrentFragment = fragment<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
fm<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.executePendingTransactions</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
((DiscoverFragment) fragment)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.refresh</span>(searchWord)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="box-sizing: border-box; position: absolute; height: 60px; right: 30px; top: 5px; color: rgb(255, 255, 255); cursor: pointer; z-index: 2;"><a target=_blank target="_blank" style="box-sizing: border-box; color: rgb(12, 137, 207);"><img src="http://static.blog.csdn.net/images/save_snippets.png" style="border: none; box-sizing: border-box;" alt="" /></a></div><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>
多加了一句fm.executePendingTransactions()
作者:jbb0403 发表于2016/10/14 11:45:46
原文链接