Android特效-视差特效

    xiaoxiao2026-08-11  12

    附上一张效果图:

    实现步骤如下:

    1、首先整体使用ListView实现,顶部的图片为ListView的HeadView

    <ImageView android:id="@+id/img" android:layout_width="match_parent" android:layout_height="200dp" android:src="@drawable/backgroud" android:scaleType="centerCrop"/>这里需要图片大于控件的大小,(来个插曲)对scaleType介绍:默认情况ImageView的ScaleType为FitCenter

    ##综上所述

    1. Matrix:不进行缩放,显示ImageView的左上角 2. Center:不进行缩放,显示ImageView的中间 3. CenterCrop:进行缩放(根据图片的比例放大到最大值,缩小到最大值,公式scale=max{ivW/imgW,ivH/imgH}),显示在ImageView中间 4. CenterInside:进行缩放(如果图片宽高都小于ImageView的宽高则不进行缩放,如果大于ImageView宽或高则按缩小到最小值scale=min{ivW/imgW,ivH/imgH})图片显示ImageView的中间 5. fitCenter:进行缩放(根据图片的比例放大到最小值,缩小到最小值min(ivW/imgW,ivH/imgH),图片显示到ImageView的中间 6. fitXY:图片高度缩小到与ImageView同高 7. fitStart:与fitCenter一样,显示到ImageView的顶部或左部 8. fitEnd:与fitCenter一样,显示到ImageView的底部或右部

    进入正题:

    2、重写手指滑动ListView的overScrollBy方法

    @Override protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { /** * deltaY: 竖直方向的瞬时偏移 顶部向下滑为- 底部向上滑为+ * scrollY: 竖直方向的偏移量 * scrollRangeY: 竖直方向滑动的范围 * maxOverScrollY: 竖直方向最大的滑动范围 * isTouchEvent: 是否为惯性 true为手指滑动 false为惯性滑动 */ if (isTouchEvent && deltaY < 0) { if (imgIv.getHeight() <= imgHeight * 2.0f / 3) {//这里因为图片太大固限制2/3 int newHeight = (int) (imgIv.getHeight() + Math.abs(deltaY / 3.0f));//每次都是最新控件的高度加上瞬时偏移 imgIv.getLayoutParams().height = newHeight; imgIv.requestLayout(); } } return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); }

    重写之后需要得到HeadView的高度,这里提供一种方法利用视图树监听

    headView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //当布局文件填充完毕 此方法会被执行 lv.setHeaderView(imgView); headView.getViewTreeObserver().removeOnGlobalLayoutListener(this);//移除监听 } }); 3、设置回弹效果,重写OnTouchEvent方法

    @Override public boolean onTouchEvent(MotionEvent ev) { switch (MotionEventCompat.getActionMasked(ev)) { case MotionEvent.ACTION_UP://当手指抬起的时候回弹到原始的位置,所以我们应该将原始高度存起来 final int startHeight = imgIv.getHeight(); final int endHeight = ivHeight; //1、只是简单的恢复到原始高度 // imgIv.getLayoutParams().height = ivHeight; // imgIv.requestLayout(); //2、定义属性动画来更新恢复 ValueAnimator animator = ValueAnimator.ofInt(1); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float fraction = animation.getAnimatedFraction();//从0.0 - 1.0 int finalHeight = evaluate(fraction, startHeight, endHeight); imgIv.getLayoutParams().height = finalHeight; imgIv.requestLayout(); } }); animator.setInterpolator(new OvershootInterpolator(6)); animator.setDuration(500); animator.start(); //3、使用自定义Animation // MyAnimation animation = new MyAnimation(imgIv, imgIv.getHeight(), ivHeight); // startAnimation(animation); break; } return super.onTouchEvent(ev); } 使用第三种的自定义Animation的代码和第二种方法类似

    @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); int finalHeight = evaluate(interpolatedTime, startHeight, endHeight); iv.getLayoutParams().height = finalHeight; iv.requestLayout(); }

    转载请注明原文地址: https://ju.6miu.com/read-1311074.html
    最新回复(0)