事实上在Android刚推出属性动画的时候。就想利用它来设计一个Banner控件,一直没什么时间尝试。

在当时看我们应用中的Banner,使用计时器来控制自己主动播放,设置一个非常大的数,利用余数原理来实现ViewPager循环。在进行内存分析的时候。看似不起眼的Banner却是一个消耗内存的大户。相信非常多App的Banner都是计时器加ViewPager的方式实现的。

近期时间比較宽裕,能够做一些研究性的工作,因此打算尝试使用属性动画实现Banner。眼下不过尝试了一下怎样实现,暂还未将其做成一个控件,最后的演示样例代码也是如此。不过实现原理的一个演示,待兴许測一下性能,假设还能够的话再做成自己定义控件。

先做一些声明:

1.这里只演示一个演示样例,说明这样的Banner的实现原理,暂未封装成控件

2.演示样例中手势滑动仅用button点击来模拟

3.因为仅演示原理。演示样例中未加入Indicator的联动效果,也没有Banner的点击响应

4.Banner的移动速度由动画时间控制,可自由设置。演示样例中设置的时间较短,故移动比較快

5.Banner尺寸临时写死了,仅适配Nexus4手机,其它手机測试请自行获取Banner宽度

6.请分别測试自己主动播放和左滑、右滑

7.上述问题皆可在封装成正式控件时解决,同一时候还有图片缓存等

8.另外Banner播放移动由属性动画控制。因此3.0下面需额外动画库nineoldandroids

先来看下效果图(动画录制的非常差,上两张静态图好了,大概能够看到Banner的移动过程):

接下来说一下实现原理,眼下仅測试了自己主动播放广告和左右滑动广告。临时未处理自己主动播放过程中的左右滑动行为。

没啥美术功底,草纸上大概画了个示意图:

以下详细来解释一下:

1.首先说明支持随意张广告,个人測试用了4张,下面直接按4张解释原理了

2.先看Banner布局。

最外层放一个FrameLayout作为容器,之所以用FrameLayout,是由于兴许须要在广告条上覆盖Indicator,即小圆点指示器(眼下演示样例里没有)。FrameLayout放一个水平的LinearLayout。该LinearLayout中依次放4个ImageView。每一个代表一幅广告。须要注意的是,初始时。手机屏幕宽度内仅显示第一幅广告。其它3个ImageView能够理解为在手机屏幕右側看不见的位置。

3.再来说怎样实现广告位的移动。大家都知道属性动画与之前的动画最大的差别就是属性动画真实地改变了其属性,比方颜色、位置等。不错,正是利用这一点,对ImageView做动画。改编其水平位置属性。达到移动广告位的目的。详细的动画实现请參考下文中的代码。

4.接下来看怎样实现Banner自己主动播放。

開始时,同一时候对4个ImageView做属性动画,将它们都向左移动一个广告位的宽度。

第一次动画完毕后。它们的位置是这种:第1个广告能够理解为移动到了手机屏幕左边的位置,手机屏幕上显示的是第2个广告。第3个。第4个广告依旧在手机屏幕右側看不到的位置。然后再次对它们4个做上述移动的动画,就这样,做完一次动画再做一次,假设没有不论什么处理的话,等第4张也移动到手机屏幕左側,再做动画就什么都看不到了,由于它们已经远远偏离手机屏幕了。因此须要做一个特别处理。就是在4个ImageView每次动画完毕之后,检查自己的位置,是否已经处于手机屏幕左側了。假设是。则又一次设置一下自己的位置。这个位置也不是随便设置的,须要将它设置到右側最后,紧跟前一个广告。这样做的效果就是每当Banner移动一次。移到左边的广告条会自己主动被又一次放到右側末尾,而不影响视觉效果。从而能够达到循环播放的效果。个人认为这样做的优点是永远仅仅有4个ImageView对象。摒弃了取余循环的方式,效率应该会有提升。

5.最后说手动左滑右滑的实现原理。因为仅仅是演示原理,本例并未真正处理手势滑动,仅用button点击来模拟。假设一直向左滑动或向右滑动比較优点理,但手势滑动不像自己主动轮播,手势滑动可左一下。右一下。随意次数的左右滑动,因此也要做特殊处理。假设向左滑动。原理同自己主动播放,利用动画将4个ImageView左移一个广告位,随后将移到左側的又一次追加到右側最后边,不论什么一次左滑也是相同的处理。因此任一次左滑结束后,一个广告当前显示,其余3个都能够觉得在手机屏幕右側。对于右滑,不同于左滑。它须要在右滑之前做处理,我们须要在右滑之前先提供可供滑动的广告位,因此须要事先把最右边的广告位拿到手机屏幕左側,然后再运行右滑处理。事实上能够这样觉得。每次右滑之前。手机屏幕左側是没有广告位的,须要预先从最右側拿1幅广告到手机屏幕左側。

以下附一些相关代码,以下是演示样例的布局代码:

<RelativeLayout xmlns: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"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity"><FrameLayoutandroid:id="@+id/banner_container"android:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><ImageViewandroid:id="@+id/banner_1"android:layout_width="704px"android:layout_height="wrap_content"android:src="@drawable/banner1" /><ImageViewandroid:id="@+id/banner_2"android:layout_width="704px"android:layout_height="wrap_content"android:src="@drawable/banner2" /><ImageViewandroid:id="@+id/banner_3"android:layout_width="704px"android:layout_height="wrap_content"android:src="@drawable/banner3" /><ImageViewandroid:id="@+id/banner_4"android:layout_width="704px"android:layout_height="wrap_content"android:src="@drawable/banner4" /></LinearLayout></FrameLayout><Buttonandroid:id="@+id/btn_start"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/banner_container"android:text="自己主动轮播" /><Buttonandroid:id="@+id/btn_stop"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/btn_start"android:enabled="false"android:text="自己主动播放与滑动请分别測试" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/btn_stop"><Buttonandroid:id="@+id/btn_left"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="模拟左滑" /><Buttonandroid:id="@+id/btn_right"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="模拟右滑"/></LinearLayout></RelativeLayout>

自己主动播放的处理代码:

    /*** 自己主动播放广告条,播放速度可由动画时间控制*/public void doAutoPlay() {for (int i = 0; i < COUNT; i++) {doAutoAnimation(imgArray[i]);}}/*** 仅适用于自己主动播放** @param v*/public void doAutoAnimation(final View v) {v.animate().x(v.getX() - v.getWidth()).setDuration(1500).setInterpolator(new LinearInterpolator()).setListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animator) {}@Overridepublic void onAnimationEnd(Animator animator) {if (v.getX() < 0) {v.setX((COUNT - 1) * v.getWidth());}doAutoAnimation(v);}@Overridepublic void onAnimationCancel(Animator animator) {}@Overridepublic void onAnimationRepeat(Animator animator) {}});}

向左滑动处理代码:

    /*** 模拟向左滑动Banner*/public void doLeftAnimation() {for (int i = 0; i < COUNT; i++) {doLeftAnimation(imgArray[i]);}}/*** 左滑之后,将滑到左边看不到的广告位移动到右边末尾** @param v*/public void doLeftAnimation(final View v) {v.animate().x(v.getX() - v.getWidth()).setDuration(1500).setInterpolator(new LinearInterpolator()).setListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animator) {}@Overridepublic void onAnimationEnd(Animator animator) {if (v.getX() < 0) {v.setX((COUNT - 1) * v.getWidth());}}@Overridepublic void onAnimationCancel(Animator animator) {}@Overridepublic void onAnimationRepeat(Animator animator) {}});}

向右滑动处理代码:

    /*** 模拟向右滑动Banner。* 因为没有採用常规的设置一个非常大数,然后取余实现循环的原理;* 本例默认N个Banner广告均在手机屏幕可见区域及右側(屏幕可见区域仅显示当前广告条)* 因此向右滑动之前。须要预先将最右側的广告条移到手机屏幕左側不可见区域*/public void doRightAnimation() {for (int i = 0; i < COUNT; i++) {if (imgArray[i].getX() == imgArray[i].getWidth() * (COUNT - 1)) {imgArray[i].setX(-imgArray[i].getWidth());break;}}for (int i = 0; i < COUNT; i++) {doRightAnimation(imgArray[i]);}}/*** 在右滑之前须要先提供一个可向右滑动的广告位*/public void doRightAnimation(final View v) {v.animate().x(v.getX() + v.getWidth()).setDuration(1500).setInterpolator(new LinearInterpolator()).setListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animator) {}@Overridepublic void onAnimationEnd(Animator animator) {}@Overridepublic void onAnimationCancel(Animator animator) {}@Overridepublic void onAnimationRepeat(Animator animator) {}});}

完整演示样例代码下载    当某天须要下载资料时,发现自己居然没有下载积分,因此设了1个积分,有须要下载的能够支持下,多谢。

利用Android属性动画实现Banner的原理与实践相关推荐

  1. 利用Android属性动画实现有趣的加载中动效

    本文目的 平时Android项目中看到的加载中的动效基本上就是转圈的形式,有点审美疲劳.前一篇文章通过ViewGroup做了一个简单的加载中的动效,上一篇文章的主要知识点基于ViewGroup实现自定 ...

  2. android+动画队列,Android属性动画详解

    前言 属性动画是Android 3.0(API 11)新加入的动画框架,属性动画弥补了视图动画的很多短板,因此已经成为大多数动画场景的首选框架. 目录 目录 1. 属性动画出现的原因 在属性动画出现以 ...

  3. Android 属性动画 详解

    Android 属性动画 详解 Android动画类型: View Animation(即所谓的Tween Animation补间动画):View Animation相当简单,不过只能支持简单的缩放. ...

  4. Android属性动画 ObjectAnimator

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/118709616 本文出自[赵彦军的博客] 文章目录 ObjectAnimator ...

  5. (转)Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法

    版权声明:本文出自郭霖的博客,转载必须注明出处. 目录(?)[-] ValueAnimator的高级用法 ObjectAnimator的高级用法 转载请注明出处:http://blog.csdn.ne ...

  6. Android 系统(196)---Android 属性动画

    Android 属性动画 属性动画 总结&攻略 前言 动画的使用 是 Android 开发中常用的知识 本文将详细介绍 Android 动画中 属性动画的原理 & 使用 动画类型 关于 ...

  7. android+属性动画+高度,android 自定义view+属性动画实现充电进度条

    近期项目中需要使用到一种类似手机电池充电进度的动画效果,以前没学属性动画的时候,是用图片+定时器的方式来完成的,最近一直在学习动画这一块,再加上复习一下自定义view的相关知识点,所以打算用属性动画和 ...

  8. Android 属性动画(一)新手入门

    一.属性动画简介 Android 中动画有很多种,属性动画就是其中的一种.所谓的属性动画,就是在指定的时间内,通过改变对象的属性达到变化效果的动画.在 Android 中,属性动画系统是一个强健的框架 ...

  9. Android属性动画完全解析(上),初识属性动画的基本用法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系 ...

最新文章

  1. 【原创 HadoopSpark 动手实践 1】Hadoop2.7.3 安装部署实践
  2. 基于Java Socket的文件UpLoad代码(完美版)-用递归解决java的目录树遍历
  3. 学习 SQL 语句 - Select(3): 条件查询与模糊查询
  4. 爬楼梯(Leetcode)
  5. css3 transtion and transform
  6. mysql怎么查找列命令_MySQL查询命令-DQL
  7. some useful tricks
  8. 前端学习(2):什么是html和css
  9. 【知识图谱】一、知识表示与知识建模
  10. Spark精华问答:DataFrame与RDD的主要区别在哪?
  11. 你真的懂病毒式营销吗
  12. android中获取 bitmap 像素的颜色 之吸管取色功能
  13. Chrome内核浏览器离线加装扩展的方法 IE Tab_v11.2.1.1
  14. Unrecognized Windows Sockets error: 10106的解决办法
  15. 全球与中国飞机内部照明系统市场深度研究分析报告(2021)
  16. 操作系统原理,物理内存“扩充”技术,内存紧缩,覆盖,交换,虚拟内存思想
  17. 华为云宝塔linux,华为云上安装宝塔面板
  18. 专用舆情监测服务公司,TOOM舆情监测公司排名全国
  19. 关闭potplayer播放器屏幕大量信息
  20. xss漏洞利用方式总结

热门文章

  1. Vue系列vue-router的配置使用(一)
  2. node-webkit学习(4)Native UI API 之window
  3. ASP.NET中获取URL重写前的原始地址
  4. Bootstrap 3 与 Foundation 5 的区别
  5. 【高清截图】UbuntuKylin 14.04 桌面版安装步骤
  6. 13个您应该安装的WordPress插件
  7. WordPress 三个必须的安全措施
  8. python——文本简单可逆加密
  9. 动态规划——最大上升子序列(hdu1087)
  10. /bin/false /sbin/nologin