bug描述
viewpager
无限循环,复用显示的view
时出现点击view
响应延迟直到下一次预加载对应view
才执行。
bug原因
viewpager
内部的view
在移出屏幕后调用了view
的onDetachedFromWindow
方法 。
因为我们无限循环的viewpager
复用view
的原因导致在viewpager
调用view
的onDetachedFromWindow
方法之前
view
又再次显示被添加到界面,被用户看见并且可以点击,在这之后viewpager
因为之前view
离开界面调用onDetachedFromWindow
方法导致点击事件没有被立即执行
直到下一次调用 dispatchAttachedToWindow
方法后才执行,导致点击事件延迟响应。
堆栈跟踪信息
E: ac26520 onDetachedFromWindow
java.lang.Exception: remove pos:2 1073741828 time:1542073406206 adapter:4c87493
at com.kanshu.ksgb.fastread.common.view.TestImage.onDetachedFromWindow(TestImage.kt:35)
at android.view.View.dispatchDetachedFromWindow(View.java:17456)
at android.view.ViewGroup.finishAnimatingView(ViewGroup.java:6723)
at android.view.View.draw(View.java:19051)
at android.view.ViewGroup.drawChild(ViewGroup.java:4216)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4026)
at android.view.View.draw(View.java:19148)
at android.support.v4.view.ViewPager.draw(ViewPager.java:2420)
at android.view.View.updateDisplayListIfDirty(View.java:18095)
at android.view.View.draw(View.java:18873)
at android.view.ViewGroup.drawChild(ViewGroup.java:4216)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4002)
at android.view.View.updateDisplayListIfDirty(View.java:18086)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4200)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4180)
at android.view.View.updateDisplayListIfDirty(View.java:18054)
E: ac26520 onTouchEvent 1542073407022
E: ac26520 onAttachedToWindow
java.lang.Exception: add pos:2 1073741831 time:1542073415028 adapter:4c87493
at com.kanshu.ksgb.fastread.common.view.TestImage.onAttachedToWindow(TestImage.kt:41)
at android.view.View.dispatchAttachedToWindow(View.java:17400)
at android.view.ViewGroup.addViewInner(ViewGroup.java:4957)
at android.view.ViewGroup.addView(ViewGroup.java:4748)
at android.support.v4.view.ViewPager.addView(ViewPager.java:1479)
at android.view.ViewGroup.addView(ViewGroup.java:4688)
at android.view.ViewGroup.addView(ViewGroup.java:4661)
at com.kanshu.ksgb.fastread.common.view.BannerLayout$LoopPagerAdapter.instantiateItem(BannerLayout.java:544)
at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1004)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1218)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:663)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:625)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:617)
at com.kanshu.ksgb.fastread.common.view.BannerLayout$1.handleMessage(BannerLayout.java:116)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:171)
at android.app.ActivityThread.main(ActivityThread.java:6699)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
关键代码
view ontouch点击事件触发
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClick();
}
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().post(action);
return true;
}
dispatchAttachedToWindow 执行之前的动作
// Transfer all pending runnables.
if (mRunQueue != null) {
mRunQueue.executeActions(info.mHandler);
mRunQueue = null;
}
网友评论