Android 百叶窗图片切换效果实现

来源:互联网 发布:php报名源码 编辑:程序博客网 时间:2024/04/29 20:43

百叶窗实现原理

 百叶窗动画,在图片过渡显示的场景中,表现为两张图片以类似百叶窗的形式,图片交织显示,慢慢由一张图片显示切换到另一张图片。 效果如下图:

这里写图片描述

百叶窗在Android的实现

在Android的实现,多种多样,我了解的就有二种形式,一种是继承View或者surfaceView,在一个控件内,通过不断绘制实现。另外一种是通个二个ImageView,其中一个绘制原图,另外一个绘制切割的矩形块覆盖在原图上,形成类似的效果,我下面的代码就是这种实现。

1. 布局

    <?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.xzj.baiyechuan.MainActivity">    <!-- 控制开始百叶窗动画的按钮 -->    <Button        android:id="@+id/button1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:text="@string/app_name" />    <!-- 父布局 -->    <RelativeLayout        android:id="@+id/box"        android:layout_width="300px"        android:layout_height="400px"        android:layout_centerHorizontal="true"        android:layout_centerVertical="true" >        <!-- 绘制原图 -->        <ImageView            android:id="@+id/imageView1"            android:layout_width="300px"            android:layout_height="400px"            android:contentDescription="@string/app_name"            android:scaleType="fitXY"            android:src="@drawable/aaa" />    </RelativeLayout></android.support.constraint.ConstraintLayout>
  1. 绘制矩形块的控件
    主要是用过PorterDuffXfermode来实现显示矩形块。其具体的原理可以参考

http://blog.csdn.net/iispring/article/details/50472485

public class TestImageView extends ImageView {    float curPosition = 0;    public TestImageView(Context context) {        super(context);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        setDraw(canvas);    }    public void setCurPosition(){        curPosition = 0.5f;        setLayerType(View.LAYER_TYPE_SOFTWARE, null);        invalidate();;    }    public void setDraw(Canvas canvas){        if (curPosition >= 1.0f) {            return;        }        int h = canvas.getHeight() / 10;        int dh;        if (curPosition < 1.0f) {            dh = (int)(h * (1 - curPosition * 1));        } else {            dh = (int)(h * (1 - curPosition) * 1);        }        for (int i=0; i<10; i++) {            canvas.drawRect(0, i*h, canvas.getWidth(), i*h+dh, CLEARING_PAINT);        }    }    private static final Paint CLEARING_PAINT;    static {        CLEARING_PAINT = new Paint();        CLEARING_PAINT.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));    }}
  1. 最后是通过属性动画实现过渡动画切换,并add到父控件中 实现其整个百叶窗效果
    TestImageView  imgView = new TestImageView (mainActivity);    imgView.setImageResource(imgRes);    imgView.setScaleType(ScaleType.FIT_XY);    LayoutParams lp = new LayoutParams(300, 400);             ((RelativeLayout)mainActivity.findViewById(R.id.box)).addView(imgView, lp);    imgView.setSwitchingStyle(ss);    ObjectAnimator animator = ObjectAnimator.ofFloat(imgView, "curPosition",                //0.001f, 0.4f, 0.5f, 1.0f);                //0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f);                1.0f);        animator.setDuration(5000);        animator.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }            @Override            public void onAnimationEnd(Animator animation) {                                     clearViewsNotOnTop((RelativeLayout)mainActivity.findViewById(R.id.box));            }           @Override           public void onAnimationCancel(Animator animation) {                isPlaying = false;            }        });        animator.start();
private void clearViewsNotOnTop(RelativeLayout parent) {        int count = parent.getChildCount();        if (count >= 2) {            parent.removeViews(0, count - 1);        }    }
0 0