最近在项目中,有用到一个仿照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); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override protected 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; } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected 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 shorter if (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(); } } @Override public 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() { @Override public 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() { @Override public 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); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { int newHeight; newHeight = (int) (originImageViewHeight + extraHeight * (1 - interpolatedTime)); mView.getLayoutParams().height = newHeight; mView.requestLayout(); } } }
第二布:在xml中,引用该ParallaxScollView:
<com.gnod.parallaxlistview.ParallaxScollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/parallax_scroll_view" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:overScrollMode="never" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ImageView android:id="@+id/headview" android:layout_width="match_parent" android:layout_height="120dp" android:scaleType="centerCrop" android:src="@drawable/img_header" /> </LinearLayout> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="15dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> </com.gnod.parallaxlistview.ParallaxScollView>
最后一步,在activity中,引用ParallaxScrollerView,并且设置imageview:
mImageView = (ImageView) findViewById(R.id.headview); scrollView = (ParallaxScollView) findViewById(R.id.parallax_scroll_view); scrollView.setParallaxImageView(mImageView);
大功告成,也可以在ScrollerView上实现炫酷的Parallax效果了
时间: 2024-11-07 06:08:51