好久没有更新博客了,积攒了很多UI效果,准备整理一下写一个系列。
作为android前端程序员,最重要的就是在工作过程中不断丰富自己的类库,等要用的时候直接拿出来改改就行了,我把它命名为Android工具箱。
今天要实现的一个效果是一个有科技感的3D ViewPager,看图:
实现这个效果主要分两个部分:
一. 无限循环ViewPager
这个网上一搜一大把,无非就是下面两种实现方式:
- 使得adapter的getCount()返回Integer.MAX_VALUE,然后在初始化的时候通过setCurrentItem()把当前页设置成一个中间值,这样左右就都有page了。然后在instantiateItem()的时候通过取模还原成真实的index。
数据集前后各补一个(比如123补成31231),然后监听viewpager的滑动,在onPageScrollStateChanged() 里通过setCurrentItem()设置真正的页面index。
第一种方法比较简单一些,而且逻辑清晰,github上有现成的封装:
https://github.com/antonyt/InfiniteViewPager
但是实际使用的时候发现会出现ANR,重现步骤如下:
点击下方的viewpager页面,弹出上方的viewpager。左右滑动几次,按back回到下方的viewpager的时候,需要调用setCurrentItem()使得上下选择的页面一致,此时会出现ANR。究其原因,主要跟viewpager的代码实现相关:
void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) { ... ... if (mFirstLayout) { mCurItem = item; if (dispatchSelected) { dispatchOnPageSelected(item); } requestLayout(); } else { populate(item); scrollToItem(item, smoothScroll, velocity, dispatchSelected); } }
可以看到,第一次layout的时候会进上面那个代码块,但是我们back回来的时候会