package com.jacky.compatible.launcher.views;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import com.jacky.launcher.R;
import java.util.LinkedList;
import java.util.Queue;
public class FocusView extends View implements AnimatorListener {
protected String focusTag = "focus";
protected View mAnchorView;
protected int mOffsetX;
protected int mOffsetY;
protected int mOffsetWidth;
protected int mOffsetHeight;
protected int mDuration = 200;
private ObjectAnimator mObjectAnimator;
private boolean mMoving;
private boolean mMargin;
private MarginLayoutParams mLayoutParams;
private Queue<View> mQueue = new LinkedList<>();
public FocusView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(false);
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.FocusView);
mOffsetX = mTypedArray.getDimensionPixelOffset(R.styleable.FocusView_layoutOffsetX, 0);
mOffsetY = mTypedArray.getDimensionPixelOffset(R.styleable.FocusView_layoutOffsetY, 0);
mOffsetWidth = mTypedArray.getDimensionPixelOffset(R.styleable.FocusView_offsetWidth, 0);
mOffsetHeight = mTypedArray.getDimensionPixelOffset(R.styleable.FocusView_offsetHeight, 0);
mDuration = mTypedArray.getInt(R.styleable.FocusView_animDuration, 0);
mTypedArray.recycle();
}
public void setLayoutOffset(int offsetX, int offsetY) {
mOffsetX = offsetX;
mOffsetY = offsetY;
}
public void setSizeOffset(int offsetWidth, int offsetHeight) {
mOffsetWidth = offsetWidth;
mOffsetHeight = offsetHeight;
}
public void setDuration(int duration) {
mDuration = duration;
}
public View getAnchorView() {
return mAnchorView;
}
public void setAnchorView(View anchorView) {
if (anchorView == null) {
return;
}
if (mObjectAnimator != null) {
mObjectAnimator.end();
}
setVisibility(GONE);
mAnchorView = anchorView;
View view = anchorView;
if (view.findViewWithTag(focusTag) != null) {
view = view.findViewWithTag(focusTag);
}
mLayoutParams = (MarginLayoutParams) getLayoutParams();
int width = view.getWidth();
int height = view.getHeight();
int[] location = new int[2];
view.getLocationInWindow(location);
mLayoutParams.width = width + mOffsetWidth;
mLayoutParams.height = height + mOffsetHeight;
mLayoutParams.leftMargin = location[0] - mOffsetX;
mLayoutParams.topMargin = location[1] - mOffsetY;
setX(mLayoutParams.leftMargin);
setY(mLayoutParams.topMargin);
setTranslationX(0);
setTranslationY(0);
super.setLayoutParams(mLayoutParams);
setVisibility(VISIBLE);
}
public synchronized void moveFocus(final View targetView) {
if (targetView == null) {
return;
}
if (mMoving) {
mQueue.offer(targetView);
return;
}
mMoving = true;
if (mObjectAnimator != null) {
mObjectAnimator.cancel();
}
setVisibility(VISIBLE);
mAnchorView = targetView;
View view = targetView;
if (view.findViewWithTag(focusTag) != null) {
view = view.findViewWithTag(focusTag);
}
int[] location = new int[2];
view.getLocationInWindow(location);
int width = view.getWidth();
int height = view.getHeight();
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", location[0] - mOffsetX);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", location[1] - mOffsetY);
PropertyValuesHolder pvhW = PropertyValuesHolder.ofFloat("width", getWidth(), width + mOffsetWidth);
PropertyValuesHolder pvhH = PropertyValuesHolder.ofFloat("height", getHeight(), height + mOffsetHeight);
mObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(this, pvhW, pvhH, pvhX, pvhY);
mObjectAnimator.setDuration(mDuration);
mObjectAnimator.addListener(this);
mObjectAnimator.start();
}
public synchronized void moveMarginFocus(final View targetView) {
if (targetView == null) {
return;
}
if (mMoving) {
mQueue.offer(targetView);
return;
}
mMoving = true;
if (mObjectAnimator != null) {
mObjectAnimator.cancel();
}
setVisibility(VISIBLE);
mAnchorView = targetView;
View view = targetView;
if (view.findViewWithTag(focusTag) != null) {
view = view.findViewWithTag(focusTag);
}
int[] location = new int[2];
view.getLocationInWindow(location);
int width = view.getWidth();
int height = view.getHeight();
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("xcoor", getX(), location[0] - mOffsetX);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("ycoor", getY(), location[1] - mOffsetY);
PropertyValuesHolder pvhW = PropertyValuesHolder.ofFloat("width", getWidth(), width + mOffsetWidth);
PropertyValuesHolder pvhH = PropertyValuesHolder.ofFloat("height", getHeight(), height + mOffsetHeight);
mObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(this, pvhW, pvhH, pvhX, pvhY);
mObjectAnimator.setDuration(mDuration);
mObjectAnimator.addListener(this);
mObjectAnimator.start();
}
public boolean canMove() {
return mQueue.size() < 1;
}
@Override
public void onAnimationStart(Animator animation) {
mMoving = true;
}
@Override
public void onAnimationEnd(Animator animation) {
mMoving = false;
if (!mQueue.isEmpty()) {
View anchorView = mQueue.poll();
if (mMargin)
moveMarginFocus(anchorView);
else
moveFocus(anchorView);
}
}
@Override
public void onAnimationCancel(Animator animation) {
mMoving = false;
}
@Override
public void onAnimationRepeat(Animator animation) {
// TODO Auto-generated method stub
}
public void setXcoor(float x) {
if (mLayoutParams != null) {
mLayoutParams.leftMargin = (int) x;
super.setLayoutParams(mLayoutParams);
}
}
public void setYcoor(float y) {
if (mLayoutParams != null) {
mLayoutParams.topMargin = (int) y;
super.setLayoutParams(mLayoutParams);
}
}
public void setWidth(float width) {
if (mLayoutParams != null && mLayoutParams.width != (int) width) {
mLayoutParams.width = (int) width;
super.setLayoutParams(mLayoutParams);
}
}
public void setHeight(float height) {
if (mLayoutParams != null && mLayoutParams.height != (int) height) {
mLayoutParams.height = (int) height;
super.setLayoutParams(mLayoutParams);
}
}
public void setMargin(boolean margin) {
mMargin = margin;
}
}