利用Android属性动画实现Banner的原理与实践Word格式.docx
《利用Android属性动画实现Banner的原理与实践Word格式.docx》由会员分享,可在线阅读,更多相关《利用Android属性动画实现Banner的原理与实践Word格式.docx(12页珍藏版)》请在冰豆网上搜索。
先来看下效果图(动画录制的很差,上两张静态图好了,大概可以看到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.最后说手动左滑右滑的实现原理。
由于只是演示原理,本例并未真正处理手势滑动,仅用按钮点击来模拟。
如果一直向左滑动或向右滑动比较好处理,但手势滑动不像自动轮播,手势滑动可左一下,右一下,任意次数的左右滑动,因此也要做特殊处理。
如果向左滑动,原理同自动播放,利用动画将4个ImageView左移一个广告位,随后将移到左侧的重新追加到右侧最后边,任何一次左滑也是同样的处理,因此任一次左滑结束后,一个广告当前显示,其余3个都可以认为在手机屏幕右侧。
对于右滑,不同于左滑,它需要在右滑之前做处理,我们需要在右滑之前先提供可供滑动的广告位,因此需要事先把最右边的广告位拿到手机屏幕左侧,然后再执行右滑处理。
其实可以这样认为,每次右滑之前,手机屏幕左侧是没有广告位的,需要预先从最右侧拿1幅广告到手机屏幕左侧。
下面附一些相关代码,以下是示例的布局代码:
[html]viewplaincopy
android:
layout_width="
match_parent"
android:
layout_height="
paddingBottom="
@dimen/activity_vertical_margin"
paddingLeft="
@dimen/activity_horizontal_margin"
paddingRight="
paddingTop="
tools:
context="
.MainActivity"
>
<
FrameLayout
id="
@+id/banner_container"
wrap_content"
LinearLayout
orientation="
horizontal"
ImageView
@+id/banner_1"
704px"
src="
@drawable/banner1"
/>
@+id/banner_2"
@drawable/banner2"
@+id/banner_3"
@drawable/banner3"
@+id/banner_4"
@drawable/banner4"
/LinearLayout>
/FrameLayout>
Button
@+id/btn_start"
layout_below="
text="
自动轮播"
@+id/btn_stop"
enabled="
false"
自动播放与滑动请分别测试"
@+id/btn_left"
0dp"
layout_weight="
1"
模拟左滑"
@+id/btn_right"
模拟右滑"
/>
<
/RelativeLayout>
自动播放的处理代码:
[java]viewplaincopy
/**
*自动播放广告条,播放速度可由动画时间控制
*/
publicvoiddoAutoPlay(){
for(inti=0;
i<
COUNT;
i++){
doAutoAnimation(imgArray[i]);
}
}
*仅适用于自动播放
*
*@paramv
publicvoiddoAutoAnimation(finalViewv){
v.animate().x(v.getX()-v.getWidth()).setDuration(1500).setInterpolator(newLinearInterpolator()).setListener(newAnimator.AnimatorListener(){
@Oride
publicvoidonAnimationStart(Animatoranimator){
@Override
publicvoidonAnimationEnd(Animatoranimator){
if(v.getX()<
0){
v.setX((COUNT-1)*v.getWidth());
doAutoAnimation(v);
publicvoidonAnimationCancel(Animatoranimator){
publicvoidonAnimationRepeat(Animatoranimator){
});
向左滑动处理代码:
*模拟向左滑动Banner
publicvoiddoLeftAnimation(){
doLeftAnimation(imgArray[i]);
*左滑之后,将滑到左边看不到的广告位移动到右边末尾
publicvoiddoLeftAnimation(finalViewv){
@Orride
向右滑动处理代码:
*模拟向右滑动Banner,
*由于没有采用常规的设置一个很大数,然后取余实现循环的原理;
*本例默认N个Banner广告均在手机屏幕可见区域及右侧(屏幕可见区域仅显示当前广告条)
*因此向右滑动之前,需要预先将最右侧的广告条移到手机屏幕左侧不可见区域
publicvoiddoRightAnimation(){
if(imgArray[i].getX()==imgArray[i].getWidth()*(COUNT-1)){
imgArray[i].setX(-imgArray[i].getWidth());
break;
doRightAnimation(imgArray[i]);
*在右滑之前需要先提供一个可向右滑动的广告位
publicvoiddoRightAnimation(finalViewv){
v.animate().x(v.getX()+v.getWidth()).setDuration(1500).setInterpolator(newLinearIolator()).setListener(newAnimator.AnimatorListener(){