手把手带你用viewpager实现gallary效果,外加无限循环,自动轮播
手把手带你用viewpager实现gallary效果,外加无限循环,自动轮播
效果图:图很丑,各位看官且按需更改。
主要功能:
①Gallary样式
②无限轮播
③自动轮播和手势操作间冲突解决
提前说明:可以先不看提供的连接,文章末尾会提供整体代码。
1、大致思路:
经过查阅网上资料,个人感觉viewPager实现最为靠谱,省时省力。下面就将上述的需求一个个解决:
①Gallary样式:使用ViewPager.PageTransformer解决滑动动画。
参照:
https://developer.android.com/training/animation/screen-slide.html
https://www.jianshu.com/p/722ece163629
②无限轮播:在PagerAdapter里面进行操作,让getCount()方法返回的值足够大。
参照:方法二
http://blog.csdn.net/Just_Sanpark/article/details/17436037
③自动轮播和收拾操作间冲突解决:
自动轮播使用handler发送延时消息;在viewpager的dispatchTouchEvent方法里面来进行ViewPager接收到Touch事件的操作。
2、接下来下面是代码实现了,先创建个普通的ViewPager:
①activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.tongtong.tiny.loopviewpagergallary.MainActivity"><!-- 这里的ViewPager最好包一层父布局,并给它设置android:clipChildren="false"属性--><FrameLayoutandroid:id="@+id/fl_vp_parent"android:layout_width="match_parent"android:layout_height="160dp"android:layout_centerInParent="true"android:background="#aadc71ff"android:clipChildren="false"><!-- 宽度不要占满屏幕设置android:clipChildren="false"属性 --><android.support.v4.view.ViewPagerandroid:id="@+id/id_viewpager"android:layout_width="250dp"android:layout_height="120dp"android:layout_gravity="center"android:clipChildren="false"></android.support.v4.view.ViewPager></FrameLayout></android.support.constraint.ConstraintLayout>
ViewPager:
public class PageTransformerAdapter extends PagerAdapter {private Context context;private List<TextView> list;public PageTransformerAdapter(Context context, List<TextView> list) {this.context = context;this.list = list;}@Overridepublic int getCount() {return list.size();}@Overridepublic boolean isViewFromObject(View view, Object object) {return view == object;}@Overridepublic Object instantiateItem(ViewGroup container, int position) {container.addView(list.get(position));return list.get(position);}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {TextView iv = (TextView) object;container.removeView(iv);}
}
MainActivity代码:
public class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getSimpleName();//测试数据个数public static final int LIST_SIZE = 10;FrameLayout flVpParent;ViewPager mViewPager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);flVpParent = findViewById(R.id.fl_vp_parent);mViewPager = findViewById(R.id.id_viewpager);List<TextView> viewList = getViewLists();PageTransformerAdapter mAdapter = new PageTransformerAdapter(MainActivity.this, viewList);mViewPager.setAdapter(mAdapter);}/*** 生成List<TextView>数据** @return*/private List<TextView> getViewLists() {List<TextView> list = new ArrayList<>();for (int j = 0; j < LIST_SIZE; j++) {TextView tv = generateTextView(j);list.add(tv);}return list;}/*** 生成单个的TextView对象** @param j* @return*/private TextView generateTextView(final int j) {TextView tv = new TextView(this);tv.setBackgroundColor(Color.parseColor("#2371e9"));String str = "这个是第" + (j + 1) + "个View";tv.setTag(str);tv.setText(str);tv.setTextColor(Color.parseColor("#f0523c"));tv.setTextSize(30);tv.setGravity(Gravity.CENTER);tv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Log.e(TAG, "第" + (j + 1) + "个View被点击了");}});return tv;}
}
效果如下图:
好了,架子搭建好了,可以开始一步步实现需求了。
3、Gallary视图效果:利用ViewPager.PageTransformer实现
①viewpager的布局文件设置之前已经设置好了,这里直接使用
②新建ScaleDownPageTransformer,实现ViewPager.PageTransformer接口
/*** Desc: 左右缩放的PageTransformer* Created by tiny on 2018/1/19.* Time: 17:04* Version:*/public class ScaleDownPageTransformer implements ViewPager.PageTransformer {private static final float DEFAULT_MIN_SCALE = 0.9f;private float mMinScale = DEFAULT_MIN_SCALE;/*** Apply a property transformation to the given page.** @param view Apply the transformation to this page* @param position Position of page relative to the current front-and-center* position of the pager. 0 is front and center. 1 is one full* page position to the right, and -1 is one page position to the left.*/@Overridepublic void transformPage(View view, float position) {float limitLow = -1;float limitMid = 0;float limitHigh = 1;if (position < limitLow) {view.setScaleX(mMinScale);view.setScaleY(mMinScale);} else if (position <= limitHigh) { // [-1,1]if (position < limitMid) //[-1,0){float factor = mMinScale + (1 - mMinScale) * (1 + position);view.setScaleX(factor);view.setScaleY(factor);} else//[0,1]{float factor = mMinScale + (1 - mMinScale) * (1 - position);view.setScaleX(factor);view.setScaleY(factor);}} else { // (1,+Infinity]view.setScaleX(mMinScale);view.setScaleY(mMinScale);}}
}
③将ScaleDownPageTransformer设置给viewPager对象。
//设置Page间间距
mViewPager.setPageMargin(20);
//设置缓存的页面数量
//这个如果设置为1,或者使用默认值1时,在向左滑动时,右面新加载出的view第一次加载时的缩放动画不显示。。
mViewPager.setOffscreenPageLimit(2);
mViewPager.setPageTransformer(true, new ScaleDownPageTransformer());
mViewPager.setAdapter(mAdapter);
参考官网demo:https://developer.android.com/training/animation/screen-slide.html
https://www.jianshu.com/p/722ece163629
效果如下:
4、无限循环
接下来看下无线循环的需求,具体细节和原理的说明网上有好多,我选择的是这篇文章的第二种方法。
传送门:http://blog.csdn.net/Just_Sanpark/article/details/17436037
下面直接上代码:
PagerAdapter做了些修改:
public class PageTransformerAdapter extends PagerAdapter {private Context context;private List<TextView> list;public PageTransformerAdapter(Context context, List<TextView> list) {this.context = context;this.list = list;}@Overridepublic int getCount() {return Integer.MAX_VALUE;}@Overridepublic boolean isViewFromObject(View view, Object object) {return view == object;}@Overridepublic Object instantiateItem(ViewGroup container, int position) {int actualPos = position % list.size();if (list.get(actualPos).getParent() != null) {((ViewPager) list.get(actualPos).getParent()).removeView(list.get(actualPos));}container.addView(list.get(actualPos));return list.get(actualPos);}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {TextView iv = (TextView) object;container.removeView(iv);}
}
MainActivity中增加了代码:
//这儿的1000,可以随便改,只要用户滑不出边界即可
int startPos = 1000 * viewList.size() + 1;
mViewPager.setCurrentItem(startPos);
效果如下图:
5、自动轮播,同时支持手势滑动
①自动轮播的功能决定使用handler发送消息实现
②当用户对轮播进行操作时,需要停止自动轮播的消息,这里决定在ViewPager的dispatchTouchEvent方法里面操作。
ps: 之所以不在onTouchEvent里面进行操作,是因为ViewPager对分发下来的事件进行了处理,在onTouchEvent中拦截不到ACTION_DOWN事件,长按事件也拦截不到。
代码如下:
①自定义LoopViewPager,继承自ViewPager,
/*** Desc: 自动切换的ViewPager,手势冲突已处理* Created by tiny on 2018/1/23.* Time: 14:38* Version:*/public class LoopViewPager extends ViewPager {public static final String TAG = LoopViewPager.class.getSimpleName();public LoopViewPager(Context context) {super(context);init();}public LoopViewPager(Context context, AttributeSet attrs) {super(context, attrs);init();}private void init() {autoPollTask = new AutoPollTask(this);}private static final long TIME_AUTO_POLL = 2000;private static AutoPollTask autoPollTask;private static boolean running; //标示是否正在自动轮询private static boolean canRun;//标示是否可以自动轮询,可在不需要的是否置falsestatic class AutoPollTask implements Runnable {private final WeakReference<ViewPager> mReference;//使用弱引用持有外部类引用->防止内存泄漏public AutoPollTask(ViewPager reference) {this.mReference = new WeakReference<>(reference);}@Overridepublic void run() {ViewPager viewPager = mReference.get();if (viewPager != null && running && canRun) {int currPos = viewPager.getCurrentItem();viewPager.setCurrentItem(currPos + 1, true);viewPager.postDelayed(autoPollTask, TIME_AUTO_POLL);}}}//开启:如果正在运行,先停止->再开启public void start() {if (running)stop();canRun = true;running = true;postDelayed(autoPollTask, TIME_AUTO_POLL);}public void stop() {running = false;removeCallbacks(autoPollTask);}/*** onTouchEvent中的事件被viewPager处理过了,有些拦截不到* 所以在这里拦截** @param ev* @return*/@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {//只要接收到事件,就停止滚动。if (running)stop();switch (ev.getAction()) {//当手指抬起或者划出页面时case MotionEvent.ACTION_UP:case MotionEvent.ACTION_OUTSIDE:if (canRun)start();break;}return super.dispatchTouchEvent(ev);}
}
②接下来将activity_main.xml中的ViewPager替换为LoopViewPager,并在MainActivity中添加如下代码:
mViewPager.start();
最后,为了节省资源,在MainActivity中加上下面代码。
@Override
protected void onStart() {super.onStart();if (mViewPager != null) {mViewPager.start();}
}@Override
protected void onStop() {super.onStop();if (mViewPager != null) {mViewPager.stop();}
}
最后附上福利:源码地址,求star。
https://github.com/tinyvampirepudge/LoopViewPagerGallary
手把手带你用viewpager实现gallary效果,外加无限循环,自动轮播相关推荐
- 封装一个ViewPager真正的实现图片无限循环滚动带导航点
效果图: 大家在写项目的过程中常常会碰到须要实现Viewpager里面载入几张图片来循环自己主动轮播的效果,假设不封装一下的话代码分散在activity里面会显得非常乱.并且也不利于我们下次复用,所以 ...
- html轮播图循环效果,TremulaJS-跨设备多功能的无限循环js轮播图插件
TremulaJS是一款非常酷的跨设备多功能的无限循环js轮播图插件.TremulaJS是一个客户端javascript UI组件,它基于贝兹曲线和物理动量效应制作各种效果,可以制作无限循环的图片流, ...
- Flutter PageView 实现的自动轮播图效果 Timer实现的自动轮播效果
题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精. Flutter是谷歌推出的最新的移动开发框架. [x1]微信公众号的每日提醒 随时随记 每日积累 随心而过 文章底部扫码关注 [x2] ...
- ViewPager实现左右无限循环效果
ViewPager自身并不支持左右无限循环的功能,在网上找了很多天,发现基本都是一个原理,就是实现一种假的无限循环,取一种最大值的思路,这一种方案在上一篇中实现过,并没有真正达到左右无限循环,只是一般 ...
- android开发实例之viewpager无限循环+自动滚动,Android ViewPager实现无限循环的实例...
Android ViewPager实现无限循环的实例 ViewPager自身并不支持左右无限循环的功能,这里就提供一种方案让Android ViewPager实现左右无限循环的功能,这里记录下: 用于 ...
- Android广告条效果--使用Volley实现网络图片的自动轮播(仿淘宝、网易广告页轮播效果)
最近在做自定义控件时,发现一个极其常用的效果--广告条,即图片的自动轮播效果.现在市面上大多数的APP软件都在使用这种展示广告的效果.闲来无事,我简单翻看了一下自己的手机软件,几乎都使用了这种图片自动 ...
- HTML图片重叠变换,CSS实现图片无缝无限循环展示效果
只是想练练手,看看能不能实现在页面上放置一个能无限循环滚动的图片横幅.事实证明,这并不是很难. 先看实际效果: 无限循环滚动的关键是确定宽图片的位置 首先,这个图片的设计需要有一点技巧,就是它的首位部 ...
- 微信小程序手把手教你实现类似Android中ViewPager控件效果
微信小程序手把手教你实现类似Android中ViewPager控件效果 前言 需求分析 头部TAB 滑动的内容部分 最终版本 尾巴 前言 在做Android开发的时候,ViewPager是开发者使用频 ...
- 柱状图带立体效果_PS教程!手把手教你打造立体感欧美风人像大片效果(已打包好素材资料见文末)...
在PS的众多技法中,磨皮教程种类繁多.本期教给大家的方法完全可以保留原片的细节和质感,既可以修掉面部不需要的瑕疵,又可以在保留皮肤质感的基础上,打造画面的立体感,而不是把人物的皮肤处理得如同镜面一般光 ...
最新文章
- [转]div 让文字或图片居中
- Java温故而知新(1)集合类
- Oracle数据库的认证方法、用户管理、权限管理和角色管理等
- BP神经网络算法推导
- Stanford UFLDL教程 栈式自编码算法
- Istio分层架构?80%的人有误解
- 构造函数怎么在主函数调用_C++ 虚基类及其派生类构造函数(学习笔记:第7章 12)...
- smarty二维foreach示例[顺代一维数组],再次加强版
- 【Elasticsearch】Request cannot be executed;I/O reactor status :STOPPED.
- Codeforces Round #439 (Div. 2)
- rostcm6情感分析案例分析_情感分析师在线指导情感挽回
- 如何获得学生版本的免费eviews9
- OSPF基础知识及配置命令
- linux内核编译串口驱动,ARM Linux下安装CH341串口驱动
- macbook删除windows后合并磁盘分区
- php图片虚化处理 api PHP实现生成模糊图片
- Java 基础类型 —— Short
- 简单的python爬虫程序:爬取斗鱼直播人气前五十的主播
- 使用git时代码被冲掉
- OpenCV:图片文字分割
热门文章
- ES搜索引擎-简单入门
- konfig:采用ConfigMap实现线上配置热更新
- 1000个微信小程序源码分享
- java体系的中间件适用于go吗,Go语言经典库使用分析(五)| Negroni 中间件(一)...
- linux编译符号那些事儿
- 关于「微信小程序」背后的故事
- 课堂在线录屏:EV录屏软件配置设置
- html页面如何获取已经存在的token,移动端通过携带token访问html页面
- Matlab函数gscatter使用
- Python编程PTA题解——验证“哥德巴赫猜想”