顶部图片放大回弹效果Scrollview ---- 各应用中常见的自定义View 解析

原理并不难.  代码量也不大.  非常简洁 .  先来个效果图

   再上一波代码.

public class SpecialScrollView extends ScrollView implements ViewTreeObserver.OnPreDrawListener {
    private static final String TAG = "SpecialScrollView";
    private int mOriginalHeight;
    private int drawableHeight;
    private ImageView mImage;
    private float mLastY;
    private boolean isMeasured =false;
    public SpecialScrollView(Context context) {
        super(context);
    }

    public SpecialScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public SpecialScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 设置ImageView图片, 拿到引用
     * @param mImage
     */
    public void setParallaxImage(ImageView mImage) {
        this.mImage = mImage;
        getViewTreeObserver().addOnPreDrawListener(this);


    }

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        LogUtils.i(TAG, "deltaY: " + deltaY + " scrollY: " + scrollY + " scrollRangeY: " + scrollRangeY
                + " maxOverScrollY: " + maxOverScrollY + " isTouchEvent: " + isTouchEvent);
        // 手指拉动 并且 是下拉
        if(isTouchEvent && deltaY < 0 && mImage!=null ){
            // 把拉动的瞬时变化量的绝对值交给mIamge, 就可以实现放大效果
            if(mImage.getHeight() <= drawableHeight ){
                int newHeight = (int) (mImage.getHeight() + Math.abs(deltaY / 3.0f));
                // 高度不超出图片最大高度时,才让其生效
                mImage.getLayoutParams().height = newHeight;
                mImage.requestLayout();
            }
        }

        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_UP:
                // 执行回弹动画,  属性动画\值动画
                // 从当前高度mImage.getHeight(), 执行动画到原始高度mOriginalHeight
                if (mImage!=null){
                    final int startHeight = mImage.getHeight();
                    final int endHeight = mOriginalHeight;
                    valueAnimator(startHeight, endHeight);
                }

                break;
        }
        return super.onTouchEvent(ev);
    }

    private void valueAnimator(final int startHeight, final int endHeight) {
        ValueAnimator mValueAnim = ValueAnimator.ofInt(1);
        mValueAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator mAnim) {
                float fraction = mAnim.getAnimatedFraction();
                // percent 0.0 -> 1.0
                Log.d(TAG, "fraction: " +fraction);
                Integer newHeight = evaluate(fraction, startHeight, endHeight);

                mImage.getLayoutParams().height = newHeight;
                mImage.requestLayout();
            }
        });

        mValueAnim.setInterpolator(new OvershootInterpolator());
        mValueAnim.setDuration(500);
        mValueAnim.start();
    }

    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        int startInt = startValue;
        return (int)(startInt + fraction * (endValue - startInt));
    }


    @Override
    public boolean onPreDraw() {
        if (!isMeasured) {
            mOriginalHeight = mImage.getHeight(); //
            drawableHeight = mImage.getDrawable().getIntrinsicHeight(); //
            isMeasured = true;
            LogUtils.i(TAG, "height: " + mOriginalHeight + " drawableHeight: " + drawableHeight);
        }
        return true;
    }
}

 

 

Layout布局

<?xml version="1.0" encoding="utf-8"?>
<com.Imy.Fuli.View.SpecialScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/sp_scrollview"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <ImageView
            android:src="@mipmap/bizhi"
            android:scaleType="centerCrop"
            android:id="@+id/infor_icon_bg"
            android:layout_width="match_parent"
            android:layout_height="250dp" />
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <include layout="@layout/fragment_me_having_line"></include>

            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/halving_line"/>
            <RelativeLayout
                android:background="@drawable/selector_fragment_me_item_bg"
                android:id="@+id/head_icon_setting"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="8dp">

                <TextView
                    android:paddingTop="1dp"
                    android:layout_gravity="center"
                    android:paddingLeft="15dp"
                    android:textColor="@color/color_grey_e0555555"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="16dp"
                    android:text="头像"
                    android:layout_centerVertical="true"
                    android:layout_toRightOf="@+id/collect_icon"
                    android:layout_toEndOf="@+id/collect_icon" />
                <FrameLayout
                    android:layout_marginRight="15dp"
                    android:layout_centerVertical="true"
                    android:layout_alignRight="@+id/arrow_info"
                    android:layout_width="50dp"
                    android:layout_height="50dp">
                    <com.Imy.Fuli.View.CircleImageView
                        android:id="@+id/my_uer_icon"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:src="@mipmap/user_default_photo"
                        app:civ_border_color="@color/white"
                        app:civ_border_width="2dp" />
                </FrameLayout>

                <ImageView
                    android:id="@+id/arrow_info"
                    android:layout_marginRight="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@mipmap/right_arrow"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentEnd="true" />
            </RelativeLayout>
            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/halving_line"/>
            <include layout="@layout/fragment_me_having_line"></include>
            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/halving_line"/>
            <LinearLayout
                android:orientation="vertical"
                android:background="@color/white"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <RelativeLayout
                    android:background="@drawable/selector_fragment_me_item_bg"
                    android:id="@+id/personal_info_name_layout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="8dp">

                    <TextView
                        android:paddingTop="1dp"
                        android:layout_gravity="center"
                        android:paddingLeft="15dp"
                        android:textColor="@color/color_grey_e0555555"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="16dp"
                        android:text="昵称"
                        android:layout_centerVertical="true"
                        android:layout_toRightOf="@+id/collect_icon"
                        android:layout_toEndOf="@+id/collect_icon" />
                    <ImageView
                        android:id="@+id/right_arrow_name"
                        android:layout_marginRight="10dp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/right_arrow"
                        android:layout_centerVertical="true"
                        android:layout_alignParentRight="true"
                        android:layout_alignParentEnd="true" />
                    <TextView
                        android:id="@+id/personal_info_user_name"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Imy"
                        style="@style/text_style"
                        android:layout_marginRight="15dp"
                        android:layout_centerVertical="true"
                        android:layout_toLeftOf="@+id/right_arrow_name"
                        android:layout_toStartOf="@+id/right_arrow_name" />

                </RelativeLayout>
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1px"
                    android:layout_marginLeft="24dp"
                    android:background="@color/halving_line"/>
                <RelativeLayout
                    android:background="@drawable/selector_fragment_me_item_bg"
                    android:id="@+id/personal_info_area_layout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="8dp">

                    <TextView
                        android:paddingTop="1dp"
                        android:layout_gravity="center"
                        android:paddingLeft="15dp"
                        android:textColor="@color/color_grey_e0555555"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="16dp"
                        android:text="地区"
                        android:layout_centerVertical="true"
                        android:layout_toRightOf="@+id/collect_icon"
                        android:layout_toEndOf="@+id/collect_icon" />
                    <ImageView
                        android:id="@+id/right_arrow_area"
                        android:layout_marginRight="10dp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/right_arrow"
                        android:layout_centerVertical="true"
                        android:layout_alignParentRight="true"
                        android:layout_alignParentEnd="true" />
                    <TextView
                        android:id="@+id/personal_info_address"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text=""
                        style="@style/text_style"
                        android:layout_marginRight="15dp"
                        android:layout_centerVertical="true"
                        android:layout_toLeftOf="@+id/right_arrow_area"
                        android:layout_toStartOf="@+id/right_arrow_area" />

                </RelativeLayout>
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1px"
                    android:layout_marginLeft="24dp"
                    android:background="@color/halving_line"/>
                <RelativeLayout
                    android:background="@drawable/selector_fragment_me_item_bg"
                    android:id="@+id/personal_info_sex_layout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="8dp">

                    <TextView
                        android:paddingTop="1dp"
                        android:layout_gravity="center"
                        android:paddingLeft="15dp"
                        android:textColor="@color/color_grey_e0555555"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="16dp"
                        android:text="性别"
                        android:layout_centerVertical="true"
                        android:layout_toRightOf="@+id/collect_icon"
                        android:layout_toEndOf="@+id/collect_icon" />
                    <ImageView
                        android:id="@+id/right_arrow_sex"
                        android:layout_marginRight="10dp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/right_arrow"
                        android:layout_centerVertical="true"
                        android:layout_alignParentRight="true"
                        android:layout_alignParentEnd="true" />
                    <TextView
                        android:id="@+id/personal_info_user_sex"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        style="@style/text_style"
                        android:layout_marginBottom="1dp"
                        android:layout_marginRight="15dp"
                        android:layout_centerVertical="true"
                        android:layout_toLeftOf="@+id/right_arrow_sex"
                        android:layout_toStartOf="@+id/right_arrow_sex" />
                </RelativeLayout>
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1px"
                    android:layout_marginLeft="24dp"
                    android:background="@color/halving_line"/>
                <RelativeLayout
                    android:background="@drawable/selector_fragment_me_item_bg"
                    android:id="@+id/personal_info_age_layout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="8dp">

                    <TextView
                        android:paddingTop="1dp"
                        android:layout_gravity="center"
                        android:paddingLeft="15dp"
                        android:textColor="@color/color_grey_e0555555"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="16dp"
                        android:text="年龄"
                        android:layout_centerVertical="true"
                        android:layout_toRightOf="@+id/collect_icon"
                        android:layout_toEndOf="@+id/collect_icon" />
                    <ImageView
                        android:id="@+id/right_arrow_birthday"
                        android:layout_marginRight="10dp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/right_arrow"
                        android:layout_centerVertical="true"
                        android:layout_alignParentRight="true"
                        android:layout_alignParentEnd="true" />
                    <TextView
                        android:id="@+id/personal_info_age_tv"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text=""
                        style="@style/text_style"
                        android:layout_marginRight="15dp"
                        android:layout_centerVertical="true"
                        android:layout_toLeftOf="@+id/right_arrow_birthday"
                        android:layout_toStartOf="@+id/right_arrow_birthday" />
                </RelativeLayout>
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1px"
                    android:background="@color/halving_line"/>
            </LinearLayout>

            <include layout="@layout/fragment_me_having_line"></include>
            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/halving_line"/>
            <RelativeLayout
                android:background="@drawable/selector_fragment_me_item_bg"
                android:id="@+id/personal_info_signature_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="8dp">
                <TextView
                    android:paddingTop="1dp"
                    android:layout_gravity="center"
                    android:paddingLeft="15dp"
                    android:textColor="@color/color_grey_e0555555"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="16dp"
                    android:text="个性签名"
                    android:layout_centerVertical="true"
                    android:layout_toRightOf="@+id/collect_icon"
                    android:layout_toEndOf="@+id/collect_icon" />
                <ImageView
                    android:id="@+id/right_arrow_signature"
                    android:layout_marginRight="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@mipmap/right_arrow"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentEnd="true" />
                <RelativeLayout
                    android:layout_marginRight="15dp"
                    android:layout_centerVertical="true"
                    android:layout_toLeftOf="@+id/right_arrow_signature"
                    android:layout_toStartOf="@+id/right_arrow_signature"
                    android:layout_width="200dp"
                    android:layout_height="wrap_content">
                    <TextView
                        android:id="@+id/personal_info_signature"
                        android:layout_alignParentRight="true"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="介绍下自己吧"
                        style="@style/text_style"
                        />
                </RelativeLayout>

            </RelativeLayout>
            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/halving_line"/>
        </LinearLayout>

    </LinearLayout>
</com.Imy.Fuli.View.SpecialScrollView>

  

初始化:

private void iniID() {
mSpecialScrollView = (SpecialScrollView) findViewById(R.id.sp_scrollview);
mImage = (ImageView) findViewById(R.id.infor_icon_bg);
mSpecialScrollView.setParallaxImage(mImage);
}

 

 

   快过年了 码代码的心思都没了.~ 哎呀  布局文件 可无视. 懒得写demo了. 

 

posted @ 2016-01-18 11:32  Imy_Fen  阅读(336)  评论(0编辑  收藏  举报