记录一个demo,自己很喜欢 ©程序亦非猿 InstalMaterial学习笔记之Reveal效果 ,坚持不懈向大神学习
。。
先看效果
再看代码
<pre>
package github.alex.revealview;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Interpolator;
/**
* Created by Miroslaw Stanek on 18.01.15.
*/
public class RevealView extends View {
/**填充色*/
private Paint fillPaint;
/**初始化状态*/
public static final int state_not_started = 0;
/**揭露动画开始*/
public static final int state_fill_started = 1;
/**揭露动画完成*/
public static final int state_finished = 2;
private int state = state_not_started;
/**开始的X坐标,相对于手机屏幕,不包括状态栏*/
private int startLocationX;
/**开始的Y坐标,相对于手机屏幕,不包括状态栏*/
private int startLocationY;
/**当前揭露动画的半径*/
private int currentRadius;
private ObjectAnimator revealAnimator;
private Interpolator interpolator = null;
private OnStateChangeListener onStateChangeListener;
/**揭露动画的时间*/
private int fillTime;
public RevealView(Context context) {
super(context);
}
public RevealView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
private void initView() {
fillPaint = new Paint();
fillPaint.setStyle(Paint.Style.FILL);
fillPaint.setColor(Color.WHITE);
interpolator = new AccelerateInterpolator();
fillTime = 400;
}
public void setFillColor(int color) {
fillPaint.setColor(color);
}
public void startFromLocation(int[] tapLocationOnScreen) {
changeState(state_fill_started);
startLocationX = tapLocationOnScreen[0];
startLocationY = tapLocationOnScreen[1];
/\*此时 利用反射机制 自动调用setCurrentRadius方法,并将参数传递过去\*/
revealAnimator = ObjectAnimator.ofInt(this, "currentRadius", 0, getWidth() + getHeight()).setDuration(fillTime);
revealAnimator.setInterpolator(interpolator);
revealAnimator.addListener(new MyAnimatorListenerAdapter());
revealAnimator.start();
}
private void changeState(int state) {
if (this.state == state) {
return;
}
this.state = state;
if (onStateChangeListener != null) {
onStateChangeListener.onStateChange(state);
}
}
public void setCurrentRadius(int radius) {
this.currentRadius = radius;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
if (state == state_finished) {
canvas.drawRect(0, 0, getWidth(), getHeight(), fillPaint);
} else {
canvas.drawCircle(startLocationX, startLocationY, currentRadius, fillPaint);
}
}
private final class MyAnimatorListenerAdapter extends AnimatorListenerAdapter
{
@Override
public void onAnimationEnd(Animator animation) {
changeState(state_finished);
}
}
public void setOnStateChangeListener(OnStateChangeListener onStateChangeListener) {
this.onStateChangeListener = onStateChangeListener;
}
public static interface OnStateChangeListener {
void onStateChange(int state);
}
}
</pre>
<pre>
public class NewActivity extends AppCompatActivity {
private RevealView revealView;
private int[] location;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new);
location = getIntent().getExtras().getIntArray("location");
initView();
}
private void initView() {
findViewById(R.id.bt_5).setOnClickListener(new MyOnClickListener());
revealView = (RevealView) findViewById(R.id.rv);
revealView.setVisibility(View.VISIBLE);
revealView.setFillColor(Color.parseColor("#BBFF5722"));
/*当一个视图树将要绘制时,所要调用的回调函数的接口类*/
revealView.getViewTreeObserver().addOnPreDrawListener(new MyOnPreDrawListener());
revealView.setOnStateChangeListener(new MyOnStateChangeListener());
}
private final class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
finish();
}
}
private final class MyOnStateChangeListener implements RevealView.OnStateChangeListener {
@Override
public void onStateChange(int state) {
if (state == RevealView.state_finished) {
revealView.setVisibility(View.GONE);
}
}
}
private final class MyOnPreDrawListener implements ViewTreeObserver.OnPreDrawListener {
@Override
public boolean onPreDraw() {
//必须remove掉 不然会重复调用
revealView.getViewTreeObserver().removeOnPreDrawListener(this);
revealView.startFromLocation(location);
return false;
}
}
}
</pre>