android自己定义ViewPager之——3D效果应用
今天在github里看到一个3D效果的ViewPager,感觉做出来的ViewPager滑动的时候效果十分的炫,就check out下来研究了一下怎样实现的。以及怎样使用。将整个ViewPager稍加改动后(主要是处理了一下与项目中其他控滑动控件的事件冲突)后。应用到了自己如今项目中。感觉这个效果真的很的不错。如今把自己写的一个Demo分享出来。
以下是这个ViewPager嵌入到项目中的效果图:
改动以后。在切换ViewPager时会有立体感。会为自己的应用增色不少。以下把使用的Demo发出来。事实上与使用普通的ViewPager全然一样。仅仅只是好像仅仅能用PagerAdapter及其子类Adapter为它填充数据。
1.ViewPager3D源代码:
- public class ViewPager3D extends ViewPager
- {
- /**
- * maximum overscroll rotation of the children is 90 divided by this value
- */
- final static float DEFAULT_OVERSCROLL_ROTATION = 2f;
- /**
- * maximum z distance to translate child view
- */
- final static int DEFAULT_OVERSCROLL_TRANSLATION = 150;
- /**
- * maximum z distanze during swipe
- */
- final static int DEFAULT_SWIPE_TRANSLATION = 100;
- /**
- * maximum rotation during swipe is 90 divided by this value
- */
- final static float DEFAULT_SWIPE_ROTATION = 3;
- /**
- * duration of overscroll animation in ms
- */
- final private static int DEFAULT_OVERSCROLL_ANIMATION_DURATION = 400;
- /**
- * if true alpha of children gets animated during swipe and overscroll
- */
- final private static boolean DEFAULT_ANIMATE_ALPHA = true;
- @SuppressWarnings("unused")
- private final static String DEBUG_TAG = ViewPager.class.getSimpleName();
- private final static int INVALID_POINTER_ID = -1;
- private final static double RADIANS = 180f / Math.PI;
- /**
- * @author renard
- */
- private class OverscrollEffect
- {
- private float mOverscroll;
- private Animator mAnimator;
- /**
- * @param deltaDistance [0..1] 0->no overscroll, 1>full overscroll
- */
- public void setPull(final float deltaDistance)
- {
- mOverscroll = deltaDistance;
- invalidateVisibleChilds();
- }
- /**
- * called when finger is released. starts to animate back to default
- * position
- */
- private void onRelease()
- {
- if (mAnimator != null && mAnimator.isRunning())
- {
- mAnimator.addListener(new AnimatorListener()
- {
- @Override
- public void onAnimationStart(Animator animation)
- {
- }
- @Override
- public void onAnimationRepeat(Animator animation)
- {
- }
- @Override
- public void onAnimationEnd(Animator animation)
- {
- startAnimation(0);
- }
- @Override
- public void onAnimationCancel(Animator animation)
- {
- }
- });
- mAnimator.cancel();
- }
- else
- {
- startAnimation(0);
- }
- }
- private void startAnimation(final float target)
- {
- mAnimator = ObjectAnimator.ofFloat(this, "pull", mOverscroll, target);
- mAnimator.setInterpolator(new DecelerateInterpolator());
- final float scale = Math.abs(target - mOverscroll);
- mAnimator.setDuration((long) (mOverscrollAnimationDuration * scale));
- mAnimator.start();
- }
- private boolean isOverscrolling()
- {
- if (mScrollPosition == 0 && mOverscroll < 0)
- {
- return true;
- }
- if (getAdapter() != null)
- {
- final boolean isLast = (getAdapter().getCount() - 1) == mScrollPosition;
- if (isLast && mOverscroll > 0)
- {
- return true;
- }
- }
- return false;
- }
- }
- final private OverscrollEffect mOverscrollEffect = new OverscrollEffect();
- final private Camera mCamera = new Camera();
- private OnPageChangeListener mScrollListener;
- private float mLastMotionX;
- private int mActivePointerId;
- private int mScrollPosition;
- private float mScrollPositionOffset;
- private int mScrollPositionOffsetPixels;
- final private int mTouchSlop;
- private float mOverscrollRotation;
- private float mSwipeRotation;
- private int mOverscrollTranslation;
- private int mSwipeTranslation;
- private int mOverscrollAnimationDuration;
- private boolean mAnimateAlpha;
- private Rect mTempTect = new Rect();
- public ViewPager3D(Context context, AttributeSet attrs)
- {
- super(context, attrs);
- setStaticTransformationsEnabled(true);
- final ViewConfiguration configuration = ViewConfiguration.get(context);
- mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
- super.setOnPageChangeListener(new MyOnPageChangeListener());
- init(attrs);
- }
- private void init(AttributeSet attrs)
- {
- TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ViewPager3D);
- mOverscrollRotation = a.getFloat(R.styleable.ViewPager3D_overscroll_rotation, DEFAULT_OVERSCROLL_ROTATION);
- mSwipeRotation = a.getFloat(R.styleable.ViewPager3D_swipe_rotation, DEFAULT_SWIPE_ROTATION);
- mSwipeTranslation = a.getInt(R.styleable.ViewPager3D_swipe_translation, DEFAULT_SWIPE_TRANSLATION);
- mOverscrollTranslation = a.getInt(R.styleable.ViewPager3D_overscroll_translation,
- DEFAULT_OVERSCROLL_TRANSLATION);
- mOverscrollAnimationDuration = a.getInt(R.styleable.ViewPager3D_overscroll_animation_duration,
- DEFAULT_OVERSCROLL_ANIMATION_DURATION);
- mAnimateAlpha = a.getBoolean(R.styleable.ViewPager3D_animate_alpha, DEFAULT_ANIMATE_ALPHA);
- a.recycle();
- }
- public boolean isAnimateAlpha()
- {
- return mAnimateAlpha;
- }
- public void setAnimateAlpha(boolean mAnimateAlpha)
- {
- this.mAnimateAlpha = mAnimateAlpha;
- }
- public int getOverscrollAnimationDuration()
- {
- return mOverscrollAnimationDuration;
- }
- public void setOverscrollAnimationDuration(int mOverscrollAnimationDuration)
- {
- this.mOverscrollAnimationDuration = mOverscrollAnimationDuration;
- }
- public int getSwipeTranslation()
- {
- return mSwipeTranslation;
- }
- public void setSwipeTranslation(int mSwipeTranslation)
- {
- this.mSwipeTranslation = mSwipeTranslation;
- }
- public int getOverscrollTranslation()
- {
- return mOverscrollTranslation;
- }
- public void setOverscrollTranslation(int mOverscrollTranslation)
- {
- this.mOverscrollTranslation = mOverscrollTranslation;
- }
- public float getSwipeRotation()
- {
- return mSwipeRotation;
- }
- public void setSwipeRotation(float mSwipeRotation)
- {
- this.mSwipeRotation = mSwipeRotation;
- }
- public float getOverscrollRotation()
- {
- return mOverscrollRotation;
- }
- public void setOverscrollRotation(float mOverscrollRotation)
- {
- this.mOverscrollRotation = mOverscrollRotation;
- }
- @Override
- public void setOnPageChangeListener(OnPageChangeListener listener)
- {
- mScrollListener = listener;
- }
- ;
- private void invalidateVisibleChilds()
- {
- for (int i = 0; i < getChildCount(); i++)
- {
- final View childAt = getChildAt(i);
- childAt.getLocalVisibleRect(mTempTect);
- final int area = mTempTect.width() * mTempTect.height();
- if (area > 0)
- {
- childAt.invalidate();
- }
- }
- invalidate();
- }
- private class MyOnPageChangeListener implements OnPageChangeListener
- {
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
- {
- if (mScrollListener != null)
- {
- mScrollListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
- }
- mScrollPosition = position;
- mScrollPositionOffset = positionOffset;
- mScrollPositionOffsetPixels = positionOffsetPixels;
- // Log.i(DEBUG_TAG, "mScrollPosition = " + position + " offset = " + String.format("%f.2", positionOffset));
- // Log.i(DEBUG_TAG, "onPageScrolled");
- invalidateVisibleChilds();
- }
- @Override
- public void onPageSelected(int position)
- {
- if (mScrollListener != null)
- {
- mScrollListener.onPageSelected(position);
- }
- }
- @Override
- public void onPageScrollStateChanged(final int state)
- {
- if (mScrollListener != null)
- {
- mScrollListener.onPageScrollStateChanged(state);
- }
- if (state == SCROLL_STATE_IDLE)
- {
- mScrollPositionOffset = 0;
- }
- }
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev)
- {
- final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
- switch (action)
- {
- case MotionEvent.ACTION_DOWN:
- {
- mLastMotionX = ev.getX();
- mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
- break;
- }
- case MotionEventCompat.ACTION_POINTER_DOWN:
- {
- final int index = MotionEventCompat.getActionIndex(ev);
- final float x = MotionEventCompat.getX(ev, index);
- mLastMotionX = x;
- mActivePointerId = MotionEventCompat.getPointerId(ev, index);
- break;
- }
- }
- return super.onInterceptTouchEvent(ev);
- }
- @Override
- public boolean onTouchEvent(MotionEvent ev)
- {
- boolean callSuper = false;
- final int action = ev.getAction();
- switch (action)
- {
- case MotionEvent.ACTION_DOWN:
- {
- callSuper = true;
- mLastMotionX = ev.getX();
- mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
- break;
- }
- case MotionEventCompat.ACTION_POINTER_DOWN:
- {
- callSuper = true;
- final int index = MotionEventCompat.getActionIndex(ev);
- final float x = MotionEventCompat.getX(ev, index);
- mLastMotionX = x;
- mActivePointerId = MotionEventCompat.getPointerId(ev, index);
- break;
- }
- case MotionEvent.ACTION_MOVE:
- {
- if (mActivePointerId != INVALID_POINTER_ID)
- {
- // Scroll to follow the motion event
- final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
- final float x = MotionEventCompat.getX(ev, activePointerIndex);
- final float deltaX = mLastMotionX - x;
- final int width = getWidth();
- final int widthWithMargin = width + getPageMargin();
- final int lastItemIndex = getAdapter().getCount() - 1;
- final int currentItemIndex = getCurrentItem();
- final float leftBound = Math.max(0, (currentItemIndex - 1) * widthWithMargin);
- final float rightBound = Math.min(currentItemIndex + 1, lastItemIndex) * widthWithMargin;
- if (mScrollPositionOffset == 0)
- {
- if (currentItemIndex == 0)
- {
- if (leftBound == 0)
- {
- final float over = deltaX + mTouchSlop;
- mOverscrollEffect.setPull(over / width);
- }
- }
- else if (lastItemIndex == currentItemIndex)
- {
- if (rightBound == lastItemIndex * widthWithMargin)
- {
- final float over = deltaX - mTouchSlop;
- mOverscrollEffect.setPull(over / width);
- }
- }
- }
- else
- {
- mLastMotionX = x;
- }
- }
- else
- {
- mOverscrollEffect.onRelease();
- }
- break;
- }
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- {
- callSuper = true;
- mActivePointerId = INVALID_POINTER_ID;
- mOverscrollEffect.onRelease();
- break;
- }
- case MotionEvent.ACTION_POINTER_UP:
- {
- final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
- final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
- if (pointerId == mActivePointerId)
- {
- // This was our active pointer going up. Choose a new
- // active pointer and adjust accordingly.
- final int newPointerIndex = pointerIndex == 0 ?
- 1 : 0;
- mLastMotionX = ev.getX(newPointerIndex);
- mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
- callSuper = true;
- }
- break;
- }
- }
- if (mOverscrollEffect.isOverscrolling() && !callSuper)
- {
- return true;
- }
- else
- {
- try
- {
- return super.onTouchEvent(ev);
- }
- catch (IllegalArgumentException ignore)
- {
- }
- catch (ArrayIndexOutOfBoundsException ignore)
- {
- }
- return false;
- }
- }
- @Override
- protected boolean getChildStaticTransformation(View child, Transformation t)
- {
- if (child.getWidth() == 0)
- {
- return false;
- }
- final boolean isFirstOrLast = mScrollPosition == 0 || (mScrollPosition == (getAdapter().getCount() - 1));
- if (mOverscrollEffect.isOverscrolling() && isFirstOrLast)
- {
- final float dx = getWidth() / 2;
- final int dy = getHeight() / 2;
- t.getMatrix().reset();
- final float translateZ = (float) (mOverscrollTranslation * Math.sin(Math.PI
- * Math.abs(mOverscrollEffect.mOverscroll)));
- final float degrees = 90 / mOverscrollRotation
- - (float) ((RADIANS * Math.acos(mOverscrollEffect.mOverscroll)) / mOverscrollRotation);
- mCamera.save();
- mCamera.rotateY(degrees);
- mCamera.translate(0, 0, translateZ);
- mCamera.getMatrix(t.getMatrix());
- mCamera.restore();
- t.getMatrix().preTranslate(-dx, -dy);
- t.getMatrix().postTranslate(dx, dy);
- if (mAnimateAlpha)
- {
- t.setTransformationType(Transformation.TYPE_BOTH);
- t.setAlpha((FloatMath.sin((float) ((1 - Math.abs(mOverscrollEffect.mOverscroll)) * Math.PI / 2))));
- }
- return true;
- }
- else if (mScrollPositionOffset > 0)
- {
- final float dx = getWidth() / 2;
- final float dy = getHeight() / 2;
- double degrees = 0;
- child.getLocalVisibleRect(mTempTect);
- if (mTempTect.left >= mScrollPositionOffsetPixels)
- {
- if (mAnimateAlpha)
- {
- t.setTransformationType(Transformation.TYPE_BOTH);
- t.setAlpha((FloatMath.sin((float) (mScrollPositionOffset * Math.PI / 2))));
- }
- // right side
- degrees = (90 / mSwipeRotation) - (RADIANS * Math.acos(mScrollPositionOffset)) / mSwipeRotation;
- }
- else if (mTempTect.left == 0)
- {
- if (mAnimateAlpha)
- {
- t.setTransformationType(Transformation.TYPE_BOTH);
- t.setAlpha((FloatMath.sin((float) (mScrollPositionOffset * Math.PI / 2 + Math.PI / 2))));
- }
- // left side
- degrees = -(90 / mSwipeRotation) + (RADIANS * Math.acos(1 - mScrollPositionOffset)) / mSwipeRotation;
- }
- final float translateZ = (mSwipeTranslation * FloatMath.sin((float) ((Math.PI) * mScrollPositionOffset)));
- // Log.i(DEBUG_TAG, visibleRect.left+ ", " + mScrollPositionOffsetPixels + ", degress = "+
- // String.format("%f.2", degrees));
- t.getMatrix().reset();
- mCamera.save();
- mCamera.rotateY((float) degrees);
- mCamera.translate(0, 0, translateZ);
- mCamera.getMatrix(t.getMatrix());
- mCamera.restore();
- // pivot point is center of child
- t.getMatrix().preTranslate(-dx, -dy);
- t.getMatrix().postTranslate(dx, dy);
- // child.invalidate();
- return true;
- }
- return false;
- }
- }
2.Activity中使用ViewPager3D
- package com.example.pageradapterdemo;
- import java.util.ArrayList;
- import android.os.Bundle;
- import android.support.v4.app.FragmentActivity;
- import com.focustech.common.widget.scrollviewpager.ViewPager3D;
- public class MainActivity extends FragmentActivity
- {
- private ViewPager3D mViewPager;
- private CommonFragmentAdapter mAdapter;
- private ArrayList<MyFragment> mList;
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initData();
- initView();
- }
- private void initView()
- {
- mViewPager = (ViewPager3D) findViewById(R.id.viewpager);
- mAdapter = new CommonFragmentAdapter(MainActivity.this, getSupportFragmentManager(), mList);
- mViewPager.setAdapter(mAdapter);
- }
- private void initData()
- {
- mList = new ArrayList<MyFragment>();
- MyFragment layout1 = new MyFragment("One Fragment");
- MyFragment layout2 = new MyFragment("Two Fragment");
- MyFragment layout3 = new MyFragment("Three Fragment");
- mList.add(layout1);
- mList.add(layout2);
- mList.add(layout3);
- }
- }
3.CommonFragemntAdapter为ViewPager3D填充Fragment
- public class CommonFragmentAdapter extends FragmentStatePagerAdapter
- {
- private ArrayList<MyFragment> fragmentList;
- public CommonFragmentAdapter(Activity activity, FragmentManager fm, ArrayList<MyFragment> fragmentList)
- {
- super(fm);
- this.fragmentList = fragmentList;
- }
- @Override
- public Fragment getItem(int arg0)
- {
- return fragmentList.get(arg0);
- }
- @Override
- public int getCount()
- {
- return fragmentList.size();
- }
- @Override
- public void destroyItem(ViewGroup container, int position, Object object)
- {
- super.destroyItem(container, position, object);
- }
- }
总结:将ViewPager3D当作一个普通的ViewPager来使用就可以。
android自己定义ViewPager之——3D效果应用的更多相关文章
- Android自己定义控件——3D画廊和图像矩阵
转载请注明出处:http://blog.csdn.net/allen315410/article/details/39932689 1.3D画廊的实现 我们知道android系统已经为我们提供好了一个 ...
- Android:给ViewPager添加切换效果
原文参照开发者官网:http://developer.android.com/training/animation/screen-slide.html#viewpager 以App的引导页为例: 首先 ...
- 【Android 应用开发】Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题
. 参考界面 : 携程app首页的广告栏, 使用ViewPager实现 自制页面效果图 : 源码下载地址: http://download.csdn.net/detail/han1202 ...
- Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题
. 参考界面 : 携程app首页的广告栏, 使用ViewPager实现 自制页面效果图 : 源码下载地址: http://download.csdn.net/detail/han1202 ...
- Android Camera 3D效果
一.概念 在Android中要想实现3D效果,第一个想到的应该就是OpenGL ES,因为在很多基础教材中几乎都提到了它.但是其使用起来还是稍微麻烦一些,而且它也主要用在游戏方面,那在应用方面有没有更 ...
- Android ViewPager打造3D画廊
本文已授权微信公众号:鸿洋(hongyangAndroid)在微信公众号平台原创首发. 网上有很多关于使用Gallery来打造3D画廊的博客,但是在关于Gallery的官方说法中表明: This cl ...
- Android开发之ViewPager实现多页面切换及动画效果(仿Android的Launcher效果)
Android开发中经常会有引导页或者切换页面等效果,本文采用ViewPager结合动画效果来实现仿Launcher以及页面切换的效果.源码地址在文章最后给出下载. 效果图如下: 1.Vi ...
- Android为ViewPager添加切换动画——自己定义ViewPager
转载请注明出处:http://blog.csdn.net/allen315410/article/details/44224517 在上篇博客中,我写了一个使用属性动画为ViewPager加入切换动画 ...
- Android 自己定义RecyclerView 实现真正的Gallery效果
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38173061 .本文出自:[张鸿洋的博客] 上一篇博客我使用自己定义Horizo ...
随机推荐
- 区间DP(初步了解)
区间动态规划问题一般都是考虑.对于每段区间,他们的最优值都 是由几段更小区间的最优值得到,是分治思想的一种应用,将一个区间 问题不断划分更小的区间直至一个元素组成的区间,枚举他们的组合 .求合并后的 ...
- Android的TextView使用Html来处理图片显示、字体样式、超链接等
一.[Android实例]实现TextView里的文字有不同颜色 转eoe:http://www.eoeandroid.com/thread-4496-1-1.html import android. ...
- [转载]aptitude与apt-get的区别和联系
转自 http://www.cnblogs.com/yuxc/archive/2012/08/02/2620003.html 命令 下面将要介绍的所有命令都需要sudo!使用时请将“packagena ...
- Sys.WebForms.PageRequestManagerParserErrorException:无法分析从服务器收到的消息
我引起此原因的功能如下: 在aspx页面添加按钮 JS方法: function downPPT() { $("#Btn_DownPPT").click(); } <bo ...
- 费马小定理&欧拉定理
在p是素数的情况下,对任意整数x都有xp≡x(mod p).这个定理被称作费马小定理其中如果x无法被p整除,我们有xp-1≡1(mod p).利用这条性质,在p是素数的情况下,就很容易求出一个数的逆元 ...
- 初学QML之qmlRegisterType
qmlRegisterType 是一个可以将C++实现的类在QML中调用的,连接C++和QML的一个工具 首先来看QtAssistant的介绍 int qmlRegisterType(const ch ...
- 用phpMyAdmin修改mysql数据库密码
1初始数据库密码为空. 2第一步,点击phpMyAdmin里的用户选项. 3选择root localhost用户名,点击编辑权限. 4此时会出来修改权限的页面,里面可以设置的选项还是比较多的,暂时不管 ...
- jdk,j2ee,j2se,j2me的概念区别
jdk,j2ee,j2se,j2me的概念区别1.JDK是Java development toolkit,相当于是Java的库函数,是编译,运行java程序的工具包.J2EE是Java 2 ente ...
- 鼠标悬停移除更换class
$("#xinl").mouseover(function() //鼠标悬停执行函数 { $(".xl").removeClass().addClass(&q ...
- 深入理解 静态类和静态字段(C# 基础)
序言 以前,总是被提醒,在编程过程中尽量少用静态变量,数据丢失什么的,今天有空,禁不住对静态变量的强烈好奇,跟我一起了解下静态家族的内幕吧. 静态类 定义 静态类与非静态类的重要区别在于静态类不能实例 ...