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

来源:互联网 发布:unity3d 软体材质 编辑:程序博客网 时间:2024/04/27 22:15

最近在项目中,有用到一个仿照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效果了


源码传送门









1 0
原创粉丝点击