自定义ViewPagerIndicator以及一些问题记录

自定义的ViewPagerIndicator

项目里有个地方需要用到ViewPagerIndicator,不想因为这一点小功能引入第三方库。于是就自己写了一个简单的,支持设置圆形、圆角矩形和随滑动伸缩。
在这里插入图片描述
代码还有很多可以优化的地方,就贴一点关键代码吧。

整体的思路是持有和ViewPager的itemCount相同数量的rectF和一个当前位置的rectF,通过给ViewPager添加一个滑动监听,在onPageScrolled()方法中更改当前位置的rectF的left和right值来实现伸缩效果。

   @Override
   public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (!flexible) return;
        if (currentItem >= dotsCount)
            return;
        //十分丑陋但是能实现伸缩效果的算法QAQ
        if (currentItem == position) {//左划,滑动完毕会显示+1页
            float v  = positionOffset * 2f;//放大进度,超过一半即可以到下一页
            if (v > 1) {
                v = 1;
            }
            rectF.right = rectFs[currentItem].left + dotWidth + (dotWidth + dotMargin) * v;
            if (rectF.left != rectFs[currentItem].left) {
                rectF.left = rectF.left - (rectF.left - rectFs[currentItem].left) * (1 - positionOffset);
            }
        } else {//右划,滑动完成会显示position页
            float v = 1 - positionOffset;
            v = v * 2f;
            if (v > 1)
                v = 1;
            rectF.left = rectFs[currentItem].right - dotWidth - (dotWidth + dotMargin) * v;
            if (rectF.right != rectFs[currentItem].right) {
                rectF.right = rectF.right + (rectFs[currentItem].right - rectF.right) * positionOffset;
            }
        }
        invalidate();
    }

问题记录

但是使用这个indicator的页面在多次刷新ViewPager数据之后出现了ANR,将日志文件导出之后发现是设置ViewPagerAdapter的时候每次绑定ViewPager都给adapter注册了一个匿名datasetObserver对象,而这个observer调用时又会给adapter添加另一个匿名的datasetObserver对象,于是就出现了以下运行逻辑:

  1. 初次绑定,添加了一个匿名的datasetObserver对象;
  2. ViewPager刷新,再次添加一个匿名的datasetObserver对象;
  3. ViewPager再此刷新,前两次添加的datasetObserver对象分别给adapter添加一个datasetObserver对象,此时adapter中有四个datasetObserver对象;
  4. 以此类推,viewpager刷新n次,adapter中的datasetObserver对象数量会指数级增长 -> ANR

虽然解决的方式也很简单,将datasetObserver对象作为成员变量保存,需要重新注册之前解除注册一次即可。往往是这种细节问题会导致一些很让人头疼的bug,特此记录一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ViewPagerIndicator是一个Android库,用于在ViewPager中添加指示器,以帮助用户了解当前页面的位置。它提供了多种指示器样式和自定义选项,可以轻松地与ViewPager集成。它是由Jake Wharton开发的,是一个广泛使用的库。 ### 回答2: ViewPagerIndicator是一个Android库,用于在ViewPager上添加标签指示器。它提供了一种简单而强大的方法来管理ViewPager的标签指示器,帮助用户在不同页面之间进行导航。该库是由Jake Wharton开发的,他是一位著名的Android程序员,也是Square公司的工程师。 使用ViewPagerIndicator可以为ViewPager添加多种类型的标签指示器,如圆形指示器、文字指示器、图片指示器等。你可以根据自己的需求选择合适的标签指示器样式,并自定义其外观和行为。该库支持水平和垂直方向的滑动,并兼容较旧的Android版本。 ViewPagerIndicator的使用非常简单,首先需要在项目中引入该库的依赖。然后,在布局文件中添加ViewPager和指示器,通过ViewPagerIndicator提供的适配器类将ViewPager和指示器绑定在一起。最后,你可以根据需要自定义指示器的样式、颜色等属性。 ViewPagerIndicator不仅提供了标签指示器,还包含其他一些有用的功能。例如,你可以通过ViewPagerIndicator轻松实现ViewPager的循环滚动,使第一页和最后一页之间实现无缝连接。此外,该库还支持自定义动画效果和触摸事件处理。 总之,ViewPagerIndicator是一个强大而灵活的Android库,为ViewPager添加标签指示器提供了便利。它可以帮助你更好地管理ViewPager的页面导航,并提供了丰富的自定义选项。无论是初学者还是有经验的Android开发者,都可以轻松地使用ViewPagerIndicator来改善用户界面的体验。 ### 回答3: ViewPagerIndicator是一个开源的视图指示器库,用于辅助在Android应用中实现ViewPager的指示器功能。它与ViewPager控件配合使用,为用户提供了一种方便的方式来切换页面,并显示当前页面的指示器。 ViewPagerIndicator的主要特点是简单易用和高度可定制。它提供了多种指示器样式,包括圆形、线性、文字等等,用户可以根据自己的需求选择合适的样式。同时,它还支持自定义指示器的颜色、大小、边距等属性,使用户可以完全控制指示器的外观。 除了基本的指示器功能之外,ViewPagerIndicator还提供了一些附加功能,如循环滚动、标题栏指示器等。循环滚动功能可以让用户在最后一个页面滑动时自动跳转到第一个页面,实现无限循环。标题栏指示器可以将指示器放置在标题栏上,使得用户可以在顶部直接切换页面,提升用户体验。 ViewPagerIndicator的使用也非常简单,只需要在项目中添加相应的依赖库,并在布局文件中配置指示器,然后在代码中设置ViewPager与指示器的关联即可。对于初学者来说,它是一个很好的学习资料,帮助他们快速地了解和使用ViewPager以及指示器的相关知识。 总而言之,ViewPagerIndicator是一个功能强大、简单易用的ViewPager指示器库,为开发者提供了丰富的样式和属性选择,帮助他们快速实现ViewPager的指示器功能,提升应用的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值