Android 揭露效果相容低版本
阿新 • • 發佈:2018-12-11
自定了一個ImageView,和Android揭露效果想同。
效果:
程式碼如下:
CircularRevealImageView.java
import android.content.Context; import android.graphics.Canvas; import android.graphics.Path; import android.graphics.drawable.Drawable; import android.util.AttributeSet; /** * Created by wuguangliang on 2018/11/22 * <p> * 揭露效果 * 和<code>ViewAnimationUtils.createCircularReveal</code>一樣 */ public class CircularRevealImageView extends android.support.v7.widget.AppCompatImageView { private Path path; private float centerX, centerY, startRadius, endRadius; private Thread thread; private float r = 0; private int temp = 1; private int nanos; public CircularRevealImageView(Context context) { super(context); init(); } public CircularRevealImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CircularRevealImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { path = new Path(); path.addCircle(0, 0, 0, Path.Direction.CW); initRenderThread(); } private void initRenderThread() { thread = new Thread(new Runnable() { @Override public void run() { while (r <= endRadius - startRadius && r >= 0) { try { Thread.sleep(0, nanos); r += temp; if (r < 0) { r = 0; break; } else if (r > endRadius - startRadius) { r = endRadius - startRadius; break; } } catch (InterruptedException e) { e.printStackTrace(); } } thread = null; if (r == 0) { post(new Runnable() { @Override public void run() { setImageBitmap(null); } }); } } }); } @Override protected void onDraw(Canvas canvas) { path = new Path(); path.addCircle(centerX, centerY, r, Path.Direction.CW); canvas.clipPath(path); super.onDraw(canvas); invalidate(); } /** * 開始動畫 * * @param centerX The x coordinate of the center of the animating circle, relative to * <code>view</code>. * @param centerY The y coordinate of the center of the animating circle, relative to * <code>view</code>. * @param startRadius The starting radius of the animating circle. * @param endRadius The ending radius of the animating circle. * @param nanos 執行時間,納秒 */ public void start(final float centerX, final float centerY, final float startRadius, final float endRadius, final int nanos) { temp = 1; this.centerX = centerX; this.centerY = centerY; this.startRadius = startRadius; this.endRadius = endRadius; this.nanos = nanos; if (thread == null) { initRenderThread(); } if (!thread.isAlive()) { thread.start(); } } /** * 返回動畫,直接返回到start的點。 * * @param nanos 執行時間,ns */ public void back(final int nanos) { this.nanos = nanos; temp = -1; if (thread == null) { initRenderThread(); } if (!thread.isAlive()) { thread.start(); } } /** * 返回動畫,返回到新的點 * * @param centerX The x coordinate of the center of the animating circle, relative to * <code>view</code>. * @param centerY The y coordinate of the center of the animating circle, relative to * <code>view</code>. * @param startRadius The starting radius of the animating circle. * @param endRadius The ending radius of the animating circle. * @param nanos 執行時間,ns */ public void back(final float centerX, final float centerY, final float startRadius, final float endRadius, final int nanos) { this.centerX = centerX; this.centerY = centerY; this.startRadius = startRadius; this.endRadius = endRadius; this.nanos = nanos; r = endRadius - startRadius; temp = -1; if (thread == null) { initRenderThread(); } if (!thread.isAlive()) { thread.start(); } } @Override public void setBackgroundResource(int resId) { new Throwable("不可用,用了沒效果"); } @Override public void setBackgroundDrawable(Drawable background) { new Throwable("不可用,用了沒效果"); } @Override public void setBackground(Drawable background) { new Throwable("不可用,用了沒效果"); } }
使用方式:
MainActivity.java
final CircularRevealImageView imageView = findViewById(R.id.my_image); findViewById(R.id.apex_btn_add).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { imageView.setImageDrawable(getResources().getDrawable(R.drawable.mbg_2_1)); imageView.start(500, 900, 0, 1080,200); } }); findViewById(R.id.apex_btn_remove).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { imageView.back(200); } });