Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
来源:互联网 发布:淘宝店客服怎么设置 编辑:程序博客网 时间:2024/05/18 03:32
如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456
某天看到京东商城首页的滑动广告的Banner,在流动切换的时候有立体的动画效果,感觉很有意思,然后研究了下如何实现.
废话不多说,接下来我会讲述如何实现这种效果,以及如何根据需求自定义出新的动画效果进行扩展实现.
首先还是看一下京东商城上的效果:
像一般做这种效果怎么办呢?我的建议还是先在github或者google code上搜索开源库. 一来开源库一般做得比较成熟,API封装得较好,耦合性比较低. 二来项目比较利于维护.
(并不是说全自己实现的就不好,毕竟每个人实现的思路并不一样,相对于开源库来说,阅读别人的历史代码就相对比较麻烦,有bug或者有新需求的话,会很影响开发的效率)
下面还是直接上项目, 如上所示的效果已经有开源库的实现,而且还有很多其他动画补间效果:
JazzViewPager简介:
github地址: https://github.com/jfeinstein10/JazzyViewPager
该项目是基于ViewPager的一个重写,让我们看一下自带的Demo项目结构:
这里我们可以看到,ViewPager的动画效果由nineoldandroids这个开源项目实现:
github地址:
https://github.com/JakeWharton/NineOldAndroids
该动画库将Android3.0以上版本API实现的动画做了重写,可以兼容到3.0以下的版本
JazzyViewPager的集成:
接下来我们看一下如何将该开源库集成到自己的项目中:
1.布局文件中遵照自定义控件的写法即可:
- <com.jfeinstein.jazzyviewpager.JazzyViewPager
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/jazzy_pager"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
2.设置ViewPager的动画效果:
这里首先介绍一下目前已经封装好的效果:
JazzyViewPager中的的枚举类:
- public enum TransitionEffect {
- Standard,
- Tablet,
- CubeIn,
- CubeOut,
- FlipVertical,
- FlipHorizontal,
- Stack,
- ZoomIn,
- ZoomOut,
- RotateUp,
- RotateDown,
- Accordion
- }
怎么设置呢?非常简单:
- private JazzyViewPager mJazzy;
- /* ... */
- mJazzy.setTransitionEffect(TransitionEffect.*);
在京东商城使用的效果即为TransitionEffect.CubeOut
这里我们还可以看一下其他的效果
TransitionEffect.Tablet
TransitionEffect.Stack
其他效果大家可以自己尝试下.
3.集成该开源库需要注意一些事项:
当ViewPager中的子View超过三个的时候,我们需要对PagerAdapter修改,重写InstantiateItem()方法,,会导致补间动画不能正常显示.
EX:
- private JazzyViewPager mJazzy;
- /* ... */
- @Override
- public Object instantiateItem(ViewGroup container, final int position) {
- Object obj = super.instantiateItem(container, position);
- mJazzy.setObjectForPosition(obj, position);
- return obj;
- }
JazzyViewPager的修改:
1.在枚举类中添加所需的动画效果,这里以Test代替.
- public enum TransitionEffect {
- Standard,
- Tablet,
- CubeIn,
- CubeOut,
- FlipVertical,
- FlipHorizontal,
- Stack,
- ZoomIn,
- ZoomOut,
- RotateUp,
- RotateDown,
- Accordion,
- <span style="color:#FF0000;">Test</span>
- }
2.增加动画效果的具体实现:
- protected void animateTest(View left, View right, float positionOffset) {
- if (mState != State.IDLE) {
- if (left != null) {
- //此处增加具体动画
- }
- if (right != null) {
- //此处增加具体动画实现
- }
- }
- }
3.在onPageScrolled的方法中,增加对应效果的处理:
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- if (mState == State.IDLE && positionOffset > 0) {
- oldPage = getCurrentItem();
- mState = position == oldPage ? State.GOING_RIGHT : State.GOING_LEFT;
- }
- boolean goingRight = position == oldPage;
- if (mState == State.GOING_RIGHT && !goingRight)
- mState = State.GOING_LEFT;
- else if (mState == State.GOING_LEFT && goingRight)
- mState = State.GOING_RIGHT;
- float effectOffset = isSmall(positionOffset) ? 0 : positionOffset;
- // mLeft = getChildAt(position);
- // mRight = getChildAt(position+1);
- mLeft = findViewFromObject(position);
- mRight = findViewFromObject(position+1);
- if (mFadeEnabled)
- animateFade(mLeft, mRight, effectOffset);
- if (mOutlineEnabled)
- animateOutline(mLeft, mRight);
- switch (mEffect) {
- case Standard:
- break;
- case Tablet:
- animateTablet(mLeft, mRight, effectOffset);
- break;
- case CubeIn:
- animateCube(mLeft, mRight, effectOffset, true);
- break;
- case CubeOut:
- animateCube(mLeft, mRight, effectOffset, false);
- break;
- case FlipVertical:
- animateFlipVertical(mLeft, mRight, positionOffset, positionOffsetPixels);
- break;
- case FlipHorizontal:
- animateFlipHorizontal(mLeft, mRight, effectOffset, positionOffsetPixels);
- case Stack:
- animateStack(mLeft, mRight, effectOffset, positionOffsetPixels);
- break;
- case ZoomIn:
- animateZoom(mLeft, mRight, effectOffset, true);
- break;
- case ZoomOut:
- animateZoom(mLeft, mRight, effectOffset, false);
- break;
- case RotateUp:
- animateRotate(mLeft, mRight, effectOffset, true);
- break;
- case RotateDown:
- animateRotate(mLeft, mRight, effectOffset, false);
- break;
- case Accordion:
- animateAccordion(mLeft, mRight, effectOffset);
- break;
- <span style="color:#FF0000;">case</span> <span style="color:#FF0000;">Test: </span><span class="nf">
- <span style="color:#FF0000;"> animateTest</span></span><span style="color:#FF0000;"><span class="o"></span>(mLeft, mRight, effectOffset);
- break;
- </span> }
- super.onPageScrolled(position, positionOffset, positionOffsetPixels);
- if (effectOffset == 0) {
- disableHardwareLayer();
- mState = State.IDLE;
- }
- }
经过这三步,我们就可以添加具有新的补间动画的ViewPager. 这里大家可以尽情发挥自己的创意,不断地扩展该开源库,实现自己想要的效果.
Demo下载地址:http://download.csdn.net/detail/t12x3456/6468601
这个比较详细
一、布局文件
像viewpager一样,直接写一个控件即可。
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#00ff00"> <com.jfeinstein.jazzyviewpager.JazzyViewPager xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/jazzyViewPager" android:layout_width="match_parent" android:layout_height="match_parent" > </com.jfeinstein.jazzyviewpager.JazzyViewPager></LinearLayout>
它里面还有很多属性可以定义的,像上面的可以用app这个命名空间来定义属性。下面是各种属性,基本就是各种动画,和淡入淡出效果
fadeEnable:是否有淡入淡出效果
outLineEnable:viewpager一个视图周边是否有边框
outLineColor:边框颜色
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="JazzyViewPager"> <attr name="style"> <enum name="standard" value="0" /> <enum name="tablet" value="1" /> <enum name="cubein" value="2" /> <enum name="cubeout" value="3" /> <enum name="flipvertical" value="4" /> <enum name="fliphorizontal" value="5" /> <enum name="stack" value="6" /> <enum name="zoomin" value="7" /> <enum name="zoomout" value="8" /> <enum name="rotateup" value="9" /> <enum name="rotatedown" value="10" /> <enum name="accordion" value="11" /> </attr> <attr name="fadeEnabled" format="boolean" /> <attr name="outlineEnabled" format="boolean" /> <attr name="outlineColor" format="color|reference" /> </declare-styleable></resources>
二、java代码实现
2.1首先看看它有什么动画效果,至于各种动画是什么样的,自己去试试吧~
* Standard
* Tablet
* CubeIn
* CubeOut
* FlipVertical
* FlipHorizontal
* Stack
* ZoomIn
* ZoomOut
* RotateUp
* RotateDown
* Accordion
2.2设置动画的方法
viewPager.setTransitionEffect(TransitionEffect.Tablet);
or
TransitionEffect effect = TransitionEffect.valueOf("Tablet");
setupJazziness(effect);
2.3简单设置
viewPager.setPageMargin(100);//两个页面之间的间距
viewPager.setFadeEnabled(true);//有淡入淡出效果
viewPager.setOutlineEnabled(true);//有边框
viewPager.setOutlineColor(0xff0000ff);//边框颜色
2.4适配器的写法
这里已经写的很简单了,以后照猫画虎就行。主要就是里面需要用这个viewpager做一些事情。
官方文档中说:Due to the limitations of the ViewPager
class (which JazzyViewPager
is built upon) in order to get the animations to work correctly for more than 3 Views, you'll have to add the following to theinstantiateItem
method of your PagerAdapter
.
private JazzyViewPager mJazzy;/* ... */@Overridepublic Object instantiateItem(ViewGroup container, final int position) { Object obj = super.instantiateItem(container, position); mJazzy.setObjectForPosition(obj, position); return obj;}
大概意思就是如果viewpager中的view超过3个了,就需要添加上面这个方法。这里面的obj就是一个view对象,具体参照下面的例子。
例子:
/** * @author:Jack Tony * @tips :下面的方法需要注意,尽量按照这种写法。 * @date :2014-10-22 */ class MyAdapter extends PagerAdapter{ @Override public int getCount() { // TODO 自动生成的方法存根 return 10; } @Override public boolean isViewFromObject(View view, Object obj) { if (view instanceof OutlineContainer) { return ((OutlineContainer) view).getChildAt(0) == obj; } else { return view == obj; } } /* 如果viewpager中的view超过3个就需要重写这个方法*/ @Override public Object instantiateItem(ViewGroup container, final int position) { TextView tv = new TextView(getApplicationContext()); tv.setText("Page " + (position + 1)); tv.setTextColor(Color.parseColor("#000000")); tv.setTextSize(30); tv.setGravity(Gravity.CENTER); tv.setBackground(getWallpaper()); container.addView(tv, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); //这句话必须要写,按不同的位置添加视图 viewPager.setObjectForPosition(tv, position); return tv; } @Override public void destroyItem(ViewGroup container, int position, Object obj) { container.removeView(viewPager.findViewFromObject(position)); } }
ok,这样就基本搞定了。贴上全部代码:
MainActivity.java
package com.kale.jazzviewpagertest;import android.app.ActionBar.LayoutParams;import android.app.Activity;import android.graphics.Color;import android.os.Bundle;import android.support.v4.view.PagerAdapter;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import com.jfeinstein.jazzyviewpager.JazzyViewPager;import com.jfeinstein.jazzyviewpager.JazzyViewPager.TransitionEffect;import com.jfeinstein.jazzyviewpager.OutlineContainer;public class MainActivity extends Activity { private JazzyViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = (JazzyViewPager)findViewById(R.id.jazzyViewPager); /** * 添加动画效果,可以设置很多动画效果。如: * Standard * Tablet * CubeIn * CubeOut * FlipVertical * FlipHorizontal * Stack * ZoomIn * ZoomOut * RotateUp * RotateDown * Accordion * * 下面是可以通过字符串来产生动画对象的例子: * TransitionEffect effect = TransitionEffect.valueOf("Tablet"); * setupJazziness(effect); */ viewPager.setTransitionEffect(TransitionEffect.Tablet); viewPager.setPageMargin(100);//两个页面之间的间距 viewPager.setFadeEnabled(true);//有淡入淡出效果 viewPager.setOutlineEnabled(true);//有边框 viewPager.setOutlineColor(0xff0000ff);//边框颜色 /** * 设置适配器 * 但当ViewPager中的子View超过三个的时候,我们需要对PagerAdapter修改, * 重写InstantiateItem()方法 */ viewPager.setAdapter(new MyAdapter()); viewPager.setOnPageChangeListener(null);//可以监听page的改变 } /** * @author:Jack Tony * @tips :下面的方法需要注意,尽量按照这种写法。 * @date :2014-10-22 */ class MyAdapter extends PagerAdapter{ @Override public int getCount() { // TODO 自动生成的方法存根 return 10; } @Override public boolean isViewFromObject(View view, Object obj) { if (view instanceof OutlineContainer) { return ((OutlineContainer) view).getChildAt(0) == obj; } else { return view == obj; } } /* 如果viewpager中的view超过3个就需要重写这个方法*/ @Override public Object instantiateItem(ViewGroup container, final int position) { TextView tv = new TextView(getApplicationContext()); tv.setText("Page " + (position + 1)); tv.setTextColor(Color.parseColor("#000000")); tv.setTextSize(30); tv.setGravity(Gravity.CENTER); tv.setBackground(getWallpaper()); container.addView(tv, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); //这句话必须要写,按不同的位置添加视图 viewPager.setObjectForPosition(tv, position); return tv; } @Override public void destroyItem(ViewGroup container, int position, Object obj) { container.removeView(viewPager.findViewFromObject(position)); } }}
最终效果:
扩展:
我们当然可以继续扩展动画,下面就扩展一个动画。
一、先定义一个动画名字,这里叫test
public enum TransitionEffect { Standard, Tablet, CubeIn, CubeOut, FlipVertical, FlipHorizontal, Stack, ZoomIn, ZoomOut, RotateUp, RotateDown, Accordion, Test;}
二、写实现方式
protected void animateTest(View left, View right, float positionOffset) { if (mState != State.IDLE) { if (left != null) { //此处增加具体动画 } if (right != null) { //此处增加具体动画实现 } }}
这里举一个源码中table的例子
protected void animateTablet(View left, View right, float positionOffset) { if (mState != State.IDLE) { if (left != null) { manageLayer(left, true); mRot = 30.0f * positionOffset; mTrans = getOffsetXForRotation(mRot, left.getMeasuredWidth(), left.getMeasuredHeight()); ViewHelper.setPivotX(left, left.getMeasuredWidth()/2); ViewHelper.setPivotY(left, left.getMeasuredHeight()/2); ViewHelper.setTranslationX(left, mTrans); ViewHelper.setRotationY(left, mRot); logState(left, "Left"); } if (right != null) { manageLayer(right, true); mRot = -30.0f * (1-positionOffset); mTrans = getOffsetXForRotation(mRot, right.getMeasuredWidth(), right.getMeasuredHeight()); ViewHelper.setPivotX(right, right.getMeasuredWidth()*0.5f); ViewHelper.setPivotY(right, right.getMeasuredHeight()*0.5f); ViewHelper.setTranslationX(right, mTrans); ViewHelper.setRotationY(right, mRot); logState(right, "Right"); } } }
三、添加实现代码到设置项中
@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (mState == State.IDLE && positionOffset > 0) { oldPage = getCurrentItem(); mState = position == oldPage ? State.GOING_RIGHT : State.GOING_LEFT;}boolean goingRight = position == oldPage; if (mState == State.GOING_RIGHT && !goingRight) mState = State.GOING_LEFT; else if (mState == State.GOING_LEFT && goingRight) mState = State.GOING_RIGHT; float effectOffset = isSmall(positionOffset) ? 0 : positionOffset; // mLeft = getChildAt(position); // mRight = getChildAt(position+1); mLeft = findViewFromObject(position); mRight = findViewFromObject(position+1); if (mFadeEnabled) animateFade(mLeft, mRight, effectOffset); if (mOutlineEnabled) animateOutline(mLeft, mRight); switch (mEffect) { case Standard: break; case Tablet: animateTablet(mLeft, mRight, effectOffset); break; case CubeIn: animateCube(mLeft, mRight, effectOffset, true); break; case CubeOut: animateCube(mLeft, mRight, effectOffset, false); break; case FlipVertical: animateFlipVertical(mLeft, mRight, positionOffset, positionOffsetPixels); break; case FlipHorizontal: animateFlipHorizontal(mLeft, mRight, effectOffset, positionOffsetPixels); case Stack: animateStack(mLeft, mRight, effectOffset, positionOffsetPixels); break; case ZoomIn: animateZoom(mLeft, mRight, effectOffset, true); break; case ZoomOut: animateZoom(mLeft, mRight, effectOffset, false); break; case RotateUp: animateRotate(mLeft, mRight, effectOffset, true); break; case RotateDown: animateRotate(mLeft, mRight, effectOffset, false); break; case Accordion: animateAccordion(mLeft, mRight, effectOffset); break; case Test:
animateTest(mLeft, mRight, effectOffset); break;}super.onPageScrolled(position, positionOffset, positionOffsetPixels);if (effectOffset == 0) {disableHardwareLayer();mState = State.IDLE;}}
原理和思路讲解:http://blog.csdn.net/lmj623565791/article/details/38026503
源码下载:http://download.csdn.net/detail/shark0017/8070139
参考自:http://blog.csdn.net/t12x3456/article/details/13290349
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Android 深入ViewPager实现类京东商城首页广告效果
- android高分段进阶攻略(9)——ViewPager补间动画实现京东广告Banner
- Android 深入理解ViewPager补间动画
- Android 中ViewPager 实现动画效果切换
- magento首页banner切换效果
- android用ViewPager实现带有动画效果的页面切换
- Nginx运行php的配置
- HDOJ-1024 Max Sum Plus Plus (最大M子段和问题)
- 【leetcode】Remove Linked List Elements
- 【Quartz】Quartz存储与持久化-基于quartz.properties的配置
- Android中基于HTTP的通信技术(4)使用HttpClient进行Post方式通信
- Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果
- Spark:Transformation和Action
- js 百度地图标记定位(一)
- UVA11174 J.Stand in a Line (计数+逆元)
- Storytelling in Public Speeches
- HDU 2222 Keywords Search [AC自动机]
- 第八周项目二——Time类中的运算符重载
- 2--黑马程序员---java必备基础知识总结
- 时间日期控件2