LoopViewPager+LoopIndicator
来源:互联网 发布:销售网络建设与管理 编辑:程序博客网 时间:2024/06/01 18:33
公司有个需求要在引导页增加指示的动态效果,于是臆测着效果应该是这样:
结果我想多了根本不是这么回事,算了反正有这个想法就做一下试试,本想着只做LoopIndicator后面想了想,如果ViewPager无限滑动的话指引还会指示正确吗????于是乎LoopViewPager也就一起做了。下面是干货:
主布局:
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" /> <com.example.indicator.Indicator android:id="@+id/indicator" android:background="#000000" android:layout_gravity="bottom" android:layout_width="match_parent" android:layout_height="50dp"/></FrameLayout>
MainActivity 主要代码片段:
//控件初始化让我贴出来就过分了啊。。。。。indicator.setSize(imageViews.size() - 2);//头尾增加为了循环 但实际数量不要加 viewPager.setCurrentItem(1);//设置当前位置 viewPager.addOnPageChangeListener(indicator.getOnPageChangeListener()); viewPager.addOnPageChangeListener(new LoopOnPageChangeListener(viewPager, imageViews.size()));
PagerAdapter 重要代码:
// index 0 1 2 3 4 5 // view 3 0 1 2 3 0 // 如果debug你会发现PagerAdapter加载视图的顺序 例如首次显示view 0 // instantiateItem 加载顺序为 view0 view3 view1 // 手势左滑会触发 destroyItem view3 instantiateItem view2 以此类推 @Override public Object instantiateItem(ViewGroup container, int position) { View view = views.get(position); ViewGroup viewGroup = (ViewGroup) view.getParent(); if (viewGroup != null) {//由于无限循环采用首位添加冗余的方式 // 例如本例一共4个view,但是列表里有6个。当滑动index5完全显示时会控制viewPager跳到index1 // 如果此处不判断view.getParent()的话,会发生java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. // 因为list里index5和index1的对象是同一个因此不能够重复addview(); viewGroup.removeView(view); } container.addView(view); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { //在instantiateItem里面处理 }
OnPageChangeListener 主要代码:
@Override public void onPageSelected(int position) { targetPosition = position; } @Override public void onPageScrollStateChanged(int state) { // 不在onPageSelected 里处理 // 是因为onPageSelected回调时界面可能还没有停止滑动 // 因此会产生闪烁 if (state == ViewPager.SCROLL_STATE_IDLE && targetPosition != currentPosition) { int index = targetPosition; if (targetPosition == size - 1) { index = 1; } else if (targetPosition == 0) { index = size - 2; } viewPager.setCurrentItem(index, false); currentPosition = targetPosition; } }
上面这些全部都是为了给LoopIndicator做基础,以上的知识网上一大堆不懂的可自行百度Google 关键字:android viewpager 无限循环
下面开始主题:
要想让Indicator随滑动变大变小首先要有一个缩放的比例,在OnPageChangeListener里有三个方法(自己看源码),我要的缩放比例在void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);里有回调;
具体讲讲三个参数,其中由滑动方向不同参数变化是不一样的(注意踩坑)
手势左滑:position 不变,当void onPageSelected(int position)回调时会+1 ;positionOffset 会逐渐增加(0-1);positionOffsetPixels会逐渐增加(屏幕的宽)
左滑结束:会回调一个 position+1 positionOffset=0 positionOffsetPixels=0 注意此处的处理
手势右滑:一上来就position -1 ;positionOffset 会逐渐减小(0-1);positionOffsetPixels会逐渐减小(屏幕的宽)
如果没看懂可以自己打log看一看;
知道里变化的规律代码就好写了,我用的是LayoutParams来改变ImageView的缩放(如果有性能更优的方案还请大神不吝赐教指点一二)
关键逻辑:
@Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { Log.i("ljf", "position:" + position + "---------positionoffset:" + positionOffset + "---------positionOffsetPixels:" + positionOffsetPixels); if (positionOffset == 0) { return; } if (currentPosition == position) {//判断手势方向 forward(position, positionOffset); } else { backup(position, positionOffset); } } private void forward(int position, float offset) { ImageView currentImageView = getImageView(position - 1); ImageView nextImageView = getImageView(position); action(currentImageView, nextImageView, offset); } private void backup(int position, float offset) { ImageView nextImageView = getImageView(position - 1); ImageView currentImageView = getImageView(position); action(currentImageView, nextImageView, 1 - offset); } private void action(ImageView currentImageView, ImageView nextImageView, float offset) { LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) currentImageView.getLayoutParams(); layoutParams1.width = selectWidth - (int) (normalWidth * offset); layoutParams1.height = selectWidth - (int) (normalWidth * offset); currentImageView.setLayoutParams(layoutParams1); LinearLayout.LayoutParams layoutParams2 = (LinearLayout.LayoutParams) nextImageView.getLayoutParams(); layoutParams2.width = normalWidth + (int) (normalWidth * offset); layoutParams2.height = normalWidth + (int) (normalWidth * offset); nextImageView.setLayoutParams(layoutParams2); }
这里是项目代码:https://github.com/s1991721/Android
- LoopViewPager+LoopIndicator
- Android LoopViewPager使用案例
- LoopVIewPager 第三方框架
- Android笔记之LoopViewPager笔记
- LoopViewPager可以循环播放的ViewPager
- 使用loopviewpager打造banner图轮播,带圆点
- 随便写写
- mybatis-generator扩展-自定义代码注释
- VIM命令备忘录
- c++利用STL编写简易通讯录
- RIP1 与RIP2 对比
- LoopViewPager+LoopIndicator
- 我的学习路径
- Squares POJ2002 哈希的应用
- 控制进程结束的时候,后台进程信号处理
- fill_parent、wrap_content和match_parent的区别
- 阿里云新一代关系型数据库 PolarDB 剖析
- 华为机试题
- handler以及handleThread相关的资识
- SQL数据库中的范式