ChenLittlePing / RecyclerCoverFlow

使用RecyclerView,自定义LayoutManager实现旋转木马相册效果
Apache License 2.0
833 stars 152 forks source link

最中间的item被它右边小的item盖住,层次不是在最上面 #14

Open liuyuttkx opened 6 years ago

liuyuttkx commented 6 years ago

故障复现: 1)将item间隔因数设置为0.62f, 同时将RecyclerCoverFlow高度设置为140dp,宽度充满. adapteer的item宽高设置为120dp. 这样刚好让屏幕上只显示5个item. 2)故障规律:在滑动RecyclerCoverFlow停止后,如果停止item position正好是5的倍数余1.(是以Demo中position从1开始计算) bug就会复现. 例如每屏item数量为5个, Demo滑动停止后的item position为6, 11 ,16, 21,31,36等等, 最中间的item都会被右边的item (第7,12 , 17, 22, 32,37)所盖住一部分,也就是最中间的item层级不是在最上层. 补充: 将间隔因数设置为0.6f,就不会复现这种问题

liuyuttkx commented 6 years ago

上述我提的问题, 终于已经找到了原因和解决办法. 原因: 是由于重写了RecyclerCoverFlow$getChildDrawingOrder方法, 该方法是用于控制item的绘制顺序.返回的值越大,越在后面绘制.即最中间的item是在最后绘制的. 当滑动到上述情况时,该方法返回值发生错乱.不是最中间的item最后绘制. 通过debug发现问题是由于 CoverFlowLayoutManger$getCenterPosition方法中计算方法不对导致. 方法内容如下: public int getCenterPosition() { int pos = (int) (mOffsetAll / getIntervalDistance()); int more = (int) (mOffsetAll % getIntervalDistance()); if (more > getIntervalDistance() * 0.5f ){ pos++; } return pos; } 举一列: mOffsetAll = 1128, getIntervalDistance() = 225.6 pos = 5.0,而余数应该是0.0f才对.然后由于java浮点计算时,会出现问题, 导致 more = 225.9..... 这就导致pos 本来应该是5,而最后去执行了pos++; 最终导致了item绘制顺序错乱.

解决方法: public int getCenterPosition() { float intervalDistance = getIntervalDistance(); int pos = (int) (mOffsetAll / intervalDistance); float v = pos intervalDistance; float v1 = mOffsetAll - v; if (v1 > intervalDistance 0.5f) { pos ++ ; } return pos; }