当前位置:   article > 正文

下拉放大及回弹效果_下拉回弹效果如何实现

下拉回弹效果如何实现

下拉放大及回弹效果

   ONE Goal,ONE Passion !
  • 1

我们更多地看到下拉放大,松手回弹的效果在个人中心头像布局页面使用.向下滑动的时候.头像照片会放大,松手时又会回弹回原来的大小.效果就如下:
这里写图片描述


第一:实现原理(以ListView为例)

1,当下拉时,重新设置顶部布局(一般背景为图片)的布局参数,我们只需要改变height就ok了.
2,当松开手指时,将布局参数重新设置为原来的默认值.

第二:自定义view实现
 public class SpringListView extends ListView {

    private ImageView mImageView;  // 头布局image
    int mOriginalHeight; //原始高度(圆图片的高度)
    int mSettingHeight;   //布局设置高度

    float MRATIO = 3f;   //手指滑动距离 X  让图像高度变大 (X / 3f).高度


    public SpringListView(Context context) {
        this(context, null);
    }

    public SpringListView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

    /**
     * 拿到header image的高度
     *
     * @param view
     */
    public void setHeardView(ImageView view) {
        this.mImageView = view;

        mSettingHeight = mImageView.getHeight();
        mOriginalHeight = mImageView.getDrawable().getIntrinsicHeight();

    }

    /**
     * @param deltaX         x方向瞬间变化量  顶部下拉为  -  .
     * @param deltaY
     * @param scrollX        x方向变化量
     * @param scrollY
     * @param scrollRangeX   x方向滑动范围
     * @param scrollRangeY
     * @param maxOverScrollX x方向最大滑动范围
     * @param maxOverScrollY
     * @param isTouchEvent   如果是手指滑动的话true,惯性滑动为false.
     * @return
     */
    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {


        if (deltaY < 0 && isTouchEvent) {


            if (mImageView.getHeight() <= mOriginalHeight) {   //头布局没有完全显示出来

                int cCurrentHeight = (int) (mImageView.getHeight() + Math.abs(deltaY / MRATIO));


                //改变头布局高度
                mImageView.getLayoutParams().height = cCurrentHeight;
                mImageView.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:


                //抬起时 图片高度.
                int startHeight = mImageView.getHeight();

                int endHeight = mSettingHeight;


                startAnim(startHeight, endHeight);

                break;
        }

        //此次不能返回 true.  如果返回true的话,那么overScrollBy将不会执行了.因为overScrollBy
       // 的调用必须经过onTouchEvent中调用的.
        return super.onTouchEvent(ev);
    }

    /**
     * 执行回弹动画
     *
     * @param startHeight 动画的开始位置
     * @param endHeight   动画的结束位置
     */
    private void startAnim(final int startHeight, final int endHeight) {


        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {

                // 动画执行的的比例进度
                float fraction = (float) animation.getAnimatedValue();

                // 瞬间应该回弹的距离
                float winkDis = (float) (fraction * (startHeight - endHeight));

                //设置mImageView的高度.
                mImageView.getLayoutParams().height = (int) (startHeight - winkDis);
                mImageView.requestLayout();

            }
        });

        animator.setDuration(1000);

        /**
         *   设置插值器
         *   之所以设置不同插值器后,会有不同效果.是因为
         *   插值器会改变fraction(估值器中的比例)的值.
         */

        animator.setInterpolator(new BounceInterpolator());
        animator.start();

    }


    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
第三:跑起来
 public class SpringActivity extends AppCompatActivity {

    private SpringListView lv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_spring);
        initView();
    }

    private void initView() {
        lv = (SpringListView) findViewById(R.id.lv);
    //    lv.setOverScrollMode(View.OVER_SCROLL_NEVER);
        // 加Header
        final View mHeaderView = View.inflate(this, R.layout.view_header, null);
        final ImageView mImage = (ImageView) mHeaderView.findViewById(R.id.iv);
        lv.addHeaderView(mHeaderView);


        // 填充数据
        lv.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, MyData.NAMES));



        mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                // 当布局填充结束之后, 此方法会被调用

                lv.setHeardView(mImage);

                mHeaderView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
        });
    }

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
第四:别担心,资源文件已经准备好了.

头部局 : R.layout.view_header

  <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="160dp"
        android:scaleType="centerCrop"
        android:src="@drawable/parallax_img" />

    </LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

页面布局 : R.layout.activity_spring

 <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    tools:context="com.example.customview.activity.SpringActivity">

    <com.example.customview.view.SpringListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </com.example.customview.view.SpringListView>
    </RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

欢迎走进重温经典:

  public class MyData {
    public static final String[] NAMES = new String[]{"宋江", "卢俊义", "吴用",
            "公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深",
            "武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘",
            "雷横", "李俊", "阮小二", "张横", "阮小五", " 张顺", "阮小七", "杨雄", "石秀", "解珍",
            " 解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪",
            "魏定国", "萧让", "裴宣", "欧鹏", "邓飞", " 燕顺", "杨林", "凌振", "蒋敬", "吕方",
            "郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充",
            "李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿",
            "陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩",
            "周通", "李忠", "杜兴", "汤隆", "邹渊", "邹润", "朱富", "朱贵", "蔡福", "蔡庆", "李立",
            "李云", "焦挺", "石勇", "孙新", "顾大嫂", "张青", "孙二娘", " 王定六", "郁保四", "白胜",
            "时迁", "段景柱"};
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

ok! 下来回弹效果已经完成了.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/363819
推荐阅读
相关标签
  

闽ICP备14008679号