github:https://github.com/nickeyCode/RoundImageViewPager

说实话不知道怎么描述这个效果,在网页上见得跟多,公司要求做这个效果得时候不知道怎么用文字描述找不到对应的dome只好自己写。

先上图

大概效果就是这个。主要用的的知识点就是viewpager的自定义动画。

项目目录:

roundimg是圆形图片,继承ImageView的,上网好多可以搜索得到

viewpager主要分成三部分

一是viewpager本身,设置adapter,绑定监听器等。

二是adapter,继承PagerAdapter,用法跟listview的差不多。

三是动画类,继承PageTransformer。

首先看看最核心的动画类(能做到这个效果就是根据对应的动画变动)

HeadViewPagerTransformer.Java

  1. public class HeadViewPagerTransformer implements PageTransformer{
  2. private static final float MIN_SCALE = 0.75f;
  3. //主要是设置在不同位置上的VIEW的活动动画
  4. @Override
  5. public void transformPage(View view, float position) {
  6. // TODO Auto-generated method stub
  7. int pageWidth = view.getWidth();
  8.  
  9. if (position < -) { // [-Infinity,-1)
  10. view.setAlpha();
  11. }
  12. else if (position <= ) { // [-1,0]
  13. view.setAlpha();
  14. view.setTranslationX();
  15. float x = -1.0f * (2f / 3f) * pageWidth * position;
  16. view.setTranslationX(x);
  17. float scaleFactor = MIN_SCALE + ( - MIN_SCALE) * ( - Math.abs(position));
  18. view.setScaleX(scaleFactor);
  19. view.setScaleY(scaleFactor);
  20. } else if (position <= ) { // (0,1]
  21. view.setAlpha();
  22. float x = -1.0f * (2f / 3f) * pageWidth * position;
  23. view.setTranslationX(x);
  24. float scaleFactor = MIN_SCALE + ( - MIN_SCALE) * ( - Math.abs(position));
  25. view.setScaleX(scaleFactor);
  26. view.setScaleY(scaleFactor);
  27.  
  28. }
  29. }
  30.  
  31. }

因为在这个类中,viewpager中view都有对应的位置编号,在正中间显示的view位置是0

在左边的view位置是-1,在右边的view位置是1.(相当于一个坐标轴)

只要viewpager发生滑动,就会调用tansFromPager();position之说以是float类型,是因为如果发生滑动,位置就会有对应的变化,而变化精确到0.0001.

在函数中使用if-else来设定在不同位置区间中的view的动画变化;

  1. if (position < -) { // [-Infinity,-1)
  2. view.setAlpha();
  3. }

这是负无穷到-1的区间,当然,如果你的viewpager缓存的view只有三个的话,这个就没有作用了,因为最多只有三个view,多出来就销毁了。

  1. else if (position <= ) { // [-1,0]
  2. view.setAlpha();
  3. view.setTranslationX();
  4. float x = -1.0f * (2f / 3f) * pageWidth * position;
  5. view.setTranslationX(x);
  6. float scaleFactor = MIN_SCALE + ( - MIN_SCALE) * ( - Math.abs(position));
  7. view.setScaleX(scaleFactor);
  8. view.setScaleY(scaleFactor); }

这是-1到0的区间,就是左边的view到中间或中间的view到左边的动画效果,这里主要是做了两个动画变化,一是大小,二是位置。

这两个变化公式是根据位置的变化与动画数值的关系,解二元一次方程求出来的(初中数学知识。。。。)

具体方式就是balbalblabalbalb。。。。。(不多说)

同理

  1. else if (position <= ) { // (0,1]
  2. view.setAlpha();
  3. float x = -1.0f * (2f / 3f) * pageWidth * position;
  4. view.setTranslationX(x);
  5. float scaleFactor = MIN_SCALE + ( - MIN_SCALE) * ( - Math.abs(position)); }

0到1的区间一样。在实际动画设计的过程中,公式是需要变动的。

剩下的都是普通的viewpager使用,设置adapter  (HeadViewPagerAdapter.java)

  1. public class HeadViewPagerAdapter extends PagerAdapter {
  2.  
  3. private Context mContext;
  4. private List<MyImageView> mList;
  5.  
  6. public HeadViewPagerAdapter(Context context,List<MyImageView> list){
  7. this.mContext = context;
  8. this.mList = list;
  9. }
  10.  
  11. @Override
  12. public int getCount() {
  13. // TODO Auto-generated method stub
  14. return mList.size();
  15. }
  16.  
  17. @Override
  18. public boolean isViewFromObject(View arg0, Object arg1) {
  19. // TODO Auto-generated method stub
  20. return arg0 == arg1;
  21. }
  22. //当缓存view的数量超过上限时,会销毁最先的一个
  23. @Override
  24. public void destroyItem(ViewGroup container, int position, Object object) {
  25. // TODO Auto-generated method stub
  26. //Log.d("remove", mImageViews[position].hashCode() + "");
  27. container.removeView(mList.get(position));
  28. }
  29. //添加View
  30. @Override
  31. public Object instantiateItem(ViewGroup container, int position) {
  32. // TODO Auto-generated method stub
  33. container.addView(mList.get(position),);
  34. return mList.get(position);
  35. }
  36.  
  37. }

还有就是对应的绑定:HeadViewPager.java

  1. public class HeadViewPager extends FrameLayout {
  2.  
  3. private Context mContext;
  4. private ViewPager mViewPager;
  5. private List<Integer> mImageIds;
  6. private List<MyImageView> mImageViews;
  7. private ViewGroup mViewGroup;
  8. private List<ImageView> tips;
  9. private int tipsChoseImgId;
  10. private int tipsUnchoseImgId;
  11.  
  12. public HeadViewPager(Context context, AttributeSet attrs, int defStyle) {
  13. super(context, attrs, defStyle);
  14. // TODO Auto-generated constructor stub
  15. creatView(context);
  16. }
  17.  
  18. public HeadViewPager(Context context, AttributeSet attrs) {
  19. super(context, attrs);
  20. // TODO Auto-generated constructor stub
  21. creatView(context);
  22. }
  23.  
  24. public HeadViewPager(Context context) {
  25. super(context);
  26. // TODO Auto-generated constructor stub
  27. creatView(context);
  28. }
  29.  
  30. public HeadViewPager(Context context,List<MyImageView> imgageList) {
  31. super(context);
  32. // TODO Auto-generated constructor stub
  33. creatView(context,imgageList);
  34. }
  35.  
  36. public void creatView(Context context){
  37. this.mContext = context;
  38. LayoutInflater.from(context).inflate(R.layout.head_view_pager, this);
  39. mViewPager = (ViewPager)findViewById(R.id.viewpager);
  40. mViewGroup = (ViewGroup)findViewById(R.id.viewgroup);
  41. mImageViews = new ArrayList<MyImageView>();
  42. mImageIds = new ArrayList<Integer>();
  43. tips = new ArrayList<ImageView>();
  44. tipsChoseImgId = R.drawable.img_bg_chose;
  45. tipsUnchoseImgId = R.drawable.img_bg_unchose;
  46. build();
  47. }
  48.  
  49. public void creatView(Context context,List<MyImageView> imgageList){
  50. this.mContext = context;
  51. LayoutInflater.from(context).inflate(R.layout.head_view_pager, this);
  52. mViewPager = (ViewPager)findViewById(R.id.viewpager);
  53. mViewGroup = (ViewGroup)findViewById(R.id.viewgroup);
  54. mImageViews = imgageList;
  55. mImageIds = new ArrayList<Integer>();
  56. tips = new ArrayList<ImageView>();
  57. tipsChoseImgId = R.drawable.img_bg_chose;
  58. tipsUnchoseImgId = R.drawable.img_bg_unchose;
  59. build();
  60. }
  61.  
  62. public void build(){
  63. buildTips();
  64. mViewPager.setAdapter(new HeadViewPagerAdapter(mContext,mImageViews));
  65. //设置默认显示页面为第0页
  66. mViewPager.setCurrentItem();
  67. //设置选择页面时的动画
  68. mViewPager.setPageTransformer(true, new HeadViewPagerTransformer());
  69. //设置缓存View的个数,默认是3个,这表示缓存了5个
  70. mViewPager.setOffscreenPageLimit();
  71. //页面发生改变的监听器
  72. mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
  73. //选择发生改变
  74. @Override
  75. public void onPageSelected(int arg0) {
  76. // TODO Auto-generated method stub
  77. changeTips(arg0);
  78. }
  79. //有滑动操作
  80. @Override
  81. public void onPageScrolled(int arg0, float arg1, int arg2) {
  82. // TODO Auto-generated method stub
  83.  
  84. }
  85. //滑动操作或选择改变
  86. @Override
  87. public void onPageScrollStateChanged(int arg0) {
  88. // TODO Auto-generated method stub
  89.  
  90. }
  91. });
  92.  
  93. }
  94. //初始化底部导航圆点条
  95. public void buildTips(){
  96. for (int i = ; i < mImageViews.size() ; i ++){
  97. ImageView imageView = new ImageView(mContext);
  98. imageView.setLayoutParams(new LayoutParams(,));
  99. if(i == ){
  100. imageView.setBackgroundResource(tipsChoseImgId);
  101. }else{
  102. imageView.setBackgroundResource(tipsUnchoseImgId);
  103. }
  104. LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(,));
  105. layoutParams.leftMargin = ;
  106. layoutParams.rightMargin = ;
  107. tips.add(imageView);
  108. mViewGroup.addView(imageView, layoutParams);
  109. }
  110. }
  111. //当选定的页面发生改变时,导航条也对应改变
  112. public void changeTips(int index){
  113. for (int i = ; i < tips.size() ; i ++){
  114. if(i == index){
  115. tips.get(i).setBackgroundResource(tipsChoseImgId);
  116. }else{
  117. tips.get(i).setBackgroundResource(tipsUnchoseImgId);
  118. }
  119. }
  120. }
  121.  
  122. public Context getmContext() {
  123. return mContext;
  124. }
  125.  
  126. public void setmContext(Context mContext) {
  127. this.mContext = mContext;
  128. }
  129.  
  130. public ViewPager getmViewPager() {
  131. return mViewPager;
  132. }
  133.  
  134. public void setmViewPager(ViewPager mViewPager) {
  135. this.mViewPager = mViewPager;
  136. }
  137.  
  138. public List<MyImageView> getmImageViews() {
  139. return mImageViews;
  140. }
  141. //改变图片队列时,要更新整个viewPager
  142. public void setmImageViews(List<MyImageView> mImageViews) {
  143. this.mImageViews = mImageViews;
  144. this.mViewPager.notify();
  145. this.mViewPager.setCurrentItem();
  146.  
  147. }
  148.  
  149. public ViewGroup getmViewGroup() {
  150. return mViewGroup;
  151. }
  152.  
  153. public void setmViewGroup(ViewGroup mViewGroup) {
  154. this.mViewGroup = mViewGroup;
  155. }
  156.  
  157. public int getTipsChoseImgId() {
  158. return tipsChoseImgId;
  159. }
  160.  
  161. public void setTipsChoseImgId(int tipsChoseImgId) {
  162. this.tipsChoseImgId = tipsChoseImgId;
  163. }
  164.  
  165. public int getTipsUnchoseImgId() {
  166. return tipsUnchoseImgId;
  167. }
  168.  
  169. public void setTipsUnchoseImgId(int tipsUnchoseImgId) {
  170. this.tipsUnchoseImgId = tipsUnchoseImgId;
  171. }
  172. }

样例项目资源:

http://download.csdn.NET/detail/nickey_1314/8932807

点击打开链接

Android 自定义viewpager 三张图片在同一屏幕轮播的效果的更多相关文章

  1. Android 使用ViewPager 做的半吊子的图片轮播

    Android 使用ViewPager 做的半吊子的图片轮播 效果图 虽然不咋样,但是最起码的功能是实现了,下面我们来一步步的实现它. 界面 下面我们来分析一下界面的构成 整体的布局: 因为我们要做出 ...

  2. Android项目实战(四十七):轮播图效果Viewpager

    简易.常用的轮播图效果ViewPager ,老技术了,记一笔留着以后ctrl C + ctrl V    需求如下: 不定张个数的ImagView轮播,右下角显示轮播点图标,每隔固定时间切换下一张,最 ...

  3. Android使用ViewPager实现左右循环滑动及轮播效果

    边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其 ...

  4. 巧用ViewPager 打造不一样的广告轮播切换效果

    一.概述 如果大家关注了我的微信公众号的话,一定知道我在5月6号的时候推送了一篇文章,文章名为Android超高仿QQ附近的人搜索展示(一),通过该文可以利用ViewPager实现单页显示多个Item ...

  5. Android使用ViewPager实现无限循环滑动及轮播(附源代码)

    MainActivity例如以下: package cc.ww; import java.util.ArrayList; import android.app.Activity; import and ...

  6. Android自定义视图三:给自定义视图添加“流畅”的动画

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

  7. Android中使用开源框架android-image-indicator实现图片轮播部署

    之前的博文中有介绍关于图片轮播的实现方式,分别为(含超链接): 1.<Android中使用ViewFlipper实现屏幕切换> 2.<Android中使用ViewPager实现屏幕页 ...

  8. Android开发工程师文集-Fragment,适配器,轮播图,ScrollView,Gallery 图片浏览器,Android常用布局样式

    Android开发工程师文集-Fragment,适配器,轮播图,ScrollView,Gallery 图片浏览器,Android常用布局样式 Fragment FragmentManager frag ...

  9. android 自定义Viewpager实现无限循环

    ; i < imageUrls.length; i ++){ ADInfo info = new ADInfo(); info.setUrl(imageUrls[i]); info.setCon ...

随机推荐

  1. Revolution Platform

    Revolution Platform 黑暗的极权统治现实 异类的处境 独孤的存在 觉者的形成 信仰的确立 信仰的产物 完整的思想理论 反抗与信仰的一致 反抗的超理性的智慧论 反抗的纯理性的方法论 反 ...

  2. 通达OA 小飞鱼OA实施法:以项目管理的方式来推进工作流设计项目实施

    做工作流设计的项目时,有时有几十个之多的流程须要做,并且时间有限,怎样把这些流程在有限的时间内设计完毕,并且达到预定要求成为这个项目须要解决的主要问题. 为了更好的完毕此次的工作流项目实施,在这里借鉴 ...

  3. 数据结构—单链表(类C语言描写叙述)

    单链表 1.链接存储方法 链接方式存储的线性表简称为链表(Linked List). 链表的详细存储表示为: ① 用一组随意的存储单元来存放线性表的结点(这组存储单元既能够是连续的.也能够是不连续的) ...

  4. ThinkPHP5.0框架开发--第3章 TP5.0 配置

    ThinkPHP5.0框架开发--第3章 TP5.0 配置 第3章 TP5.0 配置 ========================================================= ...

  5. [codeforces 852 D] Exploration Plan 解题报告 (二分+最大匹配)

    题目链接:http://codeforces.com/problemset/problem/852/D 题目大意: 有V个点,N个队伍,E条边,经过每条边有个时间,告诉你初始N个队伍的位置,求至少有K ...

  6. HTTP学习记录

    title: HTTP学习记录 toc: true date: 2018-09-21 20:40:48 HTTP协议,HyperText Transfer Protocol,超文本传输协议,是因特网上 ...

  7. 解决局域网内无法IP访问IIS已发布的网站

    在IIS上发布的网站,本地可以访问,但是局域网内其他电脑却访问不了,原来是防火墙的问题,关闭它就可以访问了. 上面是我的简单操作 后来又百度了一下,发现有个更详细的操作:http://jingyan. ...

  8. c#学习0217

    1 继承 继承 1 子类是否继承了父类的构造函数 答案:子类并没有继承父类的构造函数 但是子类或默认调用父类的无参数的构造函数 在子类中创建父类对象 这样子类才可以使用父类的成员 如果在父类中声明了有 ...

  9. HDU 1754 I Hate It【线段树 单点更新】

    题意:给出n个数,每次操作修改它的第s个数,询问给定区间的数的最大值 把前面两道题结合起来就可以了 自己还是敲不出来------------- #include<iostream> #in ...

  10. 路飞学城Python-Day4(practise)

    #1.请用代码实现:利用下划线将列表的每一个元素拼接成字符串,li = ['alex','eric','rain']# li = ['alex','eric','rain']# print('_'.j ...