[android] Circular Reveal 만들기
http://frogermcs.github.io/InstaMaterial-concept-part-6-user-profile/
-
Circular reveal 을 만드는 방법은 여러가지가 있다.
-
ViewAnimationUtils.createCircularReveal() 은 Render thread 통해 animation 되기 때문에 Lollipop 이전 단말에서는 사용할 수 없는 방법이다.
하지만 Lollipop 이라면 가장 간단한 방법이다.
-
https://github.com/ozodrukh/CircularReveal
위의 링크는 Ginger 이상에서 사용할 수 있는 open source
-
Circle 이 아닌 Square 방식이라면 pivotX/Y 를 지정하고 scaleX/Y 를 조정하는 것만으로 손쉽게 만들 수 있다.
-
사용하기는 어렵지만 성능측면에서 효율적인 shader 를 사용하는 방법도 있다.
아래 링크는 shader 사용에 대한 guide 를 제공한다.
http://www.curious-creature.com/2012/12/13/android-recipe-2-fun-with-shaders/
-
Custom View 를 사용해서 만들 수도 있다.
public class RevealBackgroundView extends View {
public static final int STATE_NOT_STARTED = 0;
public static final int STATE_FILL_STARTED = 1;
public static final int STATE_FINISHED = 2;
private static final Interpolator INTERPOLATOR = new AccelerateInterpolator();
private static final int FILL_TIME = 400;
private int state = STATE_NOT_STARTED;
private Paint fillPaint;
private int currentRadius;
ObjectAnimator revealAnimator;
private int startLocationX;
private int startLocationY;
private OnStateChangeListener onStateChangeListener;
public RevealBackgroundView(Context context) {
super(context);
init();
}
public RevealBackgroundView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RevealBackgroundView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public RevealBackgroundView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
fillPaint = new Paint();
fillPaint.setStyle(Paint.Style.FILL);
fillPaint.setColor(Color.WHITE);
}
public void startFromLocation(int[] tapLocationOnScreen) {
changeState(STATE_FILL_STARTED);
startLocationX = tapLocationOnScreen[0];
startLocationY = tapLocationOnScreen[1];
revealAnimator = ObjectAnimator.ofInt(this, "currentRadius", 0, getWidth() + getHeight()).setDuration(FILL_TIME);
revealAnimator.setInterpolator(INTERPOLATOR);
revealAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
changeState(STATE_FINISHED);
}
});
revealAnimator.start();
}
public void setToFinishedFrame() {
changeState(STATE_FINISHED);
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 void changeState(int state) {
if (this.state == state) {
return;
}
this.state = state;
if (onStateChangeListener != null) {
onStateChangeListener.onStateChange(state);
}
}
public void setOnStateChangeListener(OnStateChangeListener onStateChangeListener) {
this.onStateChangeListener = onStateChangeListener;
}
public void setCurrentRadius(int radius) {
this.currentRadius = radius;
invalidate();
}
public static interface OnStateChangeListener {
void onStateChange(int state);
}
}
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android] JSON lib 비교 (0) | 2017.07.21 |
---|---|
[android] 원형 progress view 그리기 (0) | 2017.07.15 |
[android] Circular Bitmap 만들기 ( 동그란 프로필 사진 ) (0) | 2017.07.13 |
[android] 특정 위치에 popup window 띄우기 (2) | 2017.07.12 |
[android] list view 의 아이템 하나씩 나타나는 animation 효과 주기 (0) | 2017.07.11 |
댓글