Android开发:Parallax效果的ScrollerView,改编自ParallaxListV

最近在项目中,,有用到一个仿照Path的Parallax效果,苦苦搜寻,在github上面,有一个类似的效果,不过是listview的,加一个顶部的headerView,实现了该效果,不过我需要的是ScrollerView的,于是对该代码进行的修改,实现了ScrollerView下面的Parallax效果,效果图参照如下:

在阅读下面代码前,可以先查看下Github上面的源码

我对于原先的代码进行了大量的删减,只实现了我需要的效果,看起来简单易懂,最怕那种绕来绕去的代码了,看核心的实现代码:

public class ParallaxScollView extends ScrollView implements OnScrollListener {public final static double NO_ZOOM = 1;public final static double ZOOM_X2 = 2;private ImageView mImageView;private int mImageViewHeight = -1;private int mDefaultImageViewHeight = 0;private int originImageViewHeight;private int mMaxHeight;private interface OnOverScrollByListener {public boolean overScrollBy(int deltaX, int deltaY, int scrollX,int scrollY, int scrollRangeX, int scrollRangeY,int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent);}private interface OnTouchEventListener {public void onTouchEvent(MotionEvent ev);}public ParallaxScollView(Context context, AttributeSet attrs,int defStyle) {super(context, attrs, defStyle);init(context);}public ParallaxScollView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}public ParallaxScollView(Context context) {super(context);init(context);}public void init(Context context) {mDefaultImageViewHeight = context.getResources().getDimensionPixelSize(R.dimen.size_default_height);originImageViewHeight = context.getResources().getDimensionPixelSize(R.dimen.size_default_height);}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {}@Overrideprotected boolean overScrollBy(int deltaX, int deltaY, int scrollX,int scrollY, int scrollRangeX, int scrollRangeY,int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {boolean isCollapseAnimation = false;isCollapseAnimation = scrollByListener.overScrollBy(deltaX, deltaY,scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX,maxOverScrollY, isTouchEvent)|| isCollapseAnimation;/*return isCollapseAnimation ? true : super.overScrollBy(deltaX, deltaY,scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX,0, isTouchEvent);*/return false;}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt) {super.onScrollChanged(l, t, oldl, oldt);View firstView = (View) mImageView.getParent();// firstView.getTop < getPaddingTop means mImageView will be covered by top padding,// so we can layout it to make it shorterif (firstView.getTop() < getPaddingTop() && mImageView.getHeight() > mImageViewHeight) {mImageView.getLayoutParams().height = Math.max(mImageView.getHeight() – (getPaddingTop() – firstView.getTop()), mImageViewHeight);// to set the firstView.mTop to 0,// maybe use View.setTop() is more easy, but it just support from Android 3.0 (API 11)firstView.layout(firstView.getLeft(), 0, firstView.getRight(), firstView.getHeight());mImageView.requestLayout();}}@Overridepublic boolean onTouchEvent(MotionEvent ev) {touchListener.onTouchEvent(ev);return super.onTouchEvent(ev);}public void setParallaxImageView(ImageView iv) {mImageView = iv;mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);}public void setViewsBounds(double zoomRatio) {if (mImageViewHeight == -1) {mImageViewHeight = mImageView.getHeight();if (mImageViewHeight <= 0) {mImageViewHeight = mDefaultImageViewHeight;}double ratio = ((double) mImageView.getDrawable().getIntrinsicWidth()) / ((double) mImageView.getWidth());}}private OnOverScrollByListener scrollByListener = new OnOverScrollByListener() {@Overridepublic boolean overScrollBy(int deltaX, int deltaY, int scrollX,int scrollY, int scrollRangeX, int scrollRangeY,int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {if (isTouchEvent) {if (true) {mImageView.getLayoutParams().height = mImageView.getHeight() – deltaY / 2;mImageView.requestLayout();}}return false;}};private OnTouchEventListener touchListener = new OnTouchEventListener() {@Overridepublic void onTouchEvent(MotionEvent ev) {if (ev.getAction() == MotionEvent.ACTION_UP) {if (mImageViewHeight – 1 < mImageView.getHeight()) {ResetAnimimation animation = new ResetAnimimation(mImageView, mImageViewHeight);animation.setDuration(300);mImageView.startAnimation(animation);}}}};public class ResetAnimimation extends Animation {int targetHeight;int originalHeight;int extraHeight;View mView;protected ResetAnimimation(View view, int targetHeight) {this.mView = view;this.targetHeight = targetHeight;originalHeight = view.getHeight();extraHeight = this.originalHeight – originImageViewHeight;Log.i("debug", "target heitht " + targetHeight + " original height " + originalHeight + " extraheight " + extraHeight);}@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {int newHeight;newHeight = (int) (originImageViewHeight + extraHeight * (1 – interpolatedTime));mView.getLayoutParams().height = newHeight;mView.requestLayout();}}}

第二布:在xml中,引用该ParallaxScollView:

哪怕前方的路会充满坎坷,但为梦想而拼搏的人会永不言败

Android开发:Parallax效果的ScrollerView,改编自ParallaxListV

相关文章:

你感兴趣的文章:

标签云: