一种带动画自定义控件方法


一般情况我们是利用View自身的setAnimation来实现动画

  1. public void UpdateViewContent()  
  2. {  
  3.     TextView txtview = (TextView)findViewById(R.id.content_view);  
  4.     txtview.setText(MyGetNextText());  
  5.     txtview.setAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));  
  6. }  

下面是对自定义控件的动画一种封装,下面代码是范例。


public class NineLinearLayout extends LinearLayout {

    private final AnimatorProxy mProxy;


    public NineLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null;
    }


    @Override
    public void setVisibility(int visibility) {
        if (mProxy != null) {
            if (visibility == GONE) {
                clearAnimation();
            } else if (visibility == VISIBLE) {
                setAnimation(mProxy);
            }
        }
        super.setVisibility(visibility);
    }


    public float getAlpha() {
        if (AnimatorProxy.NEEDS_PROXY) {
            return mProxy.getAlpha();
        } else {
            return super.getAlpha();
        }
    }
    public void setAlpha(float alpha) {
        if (AnimatorProxy.NEEDS_PROXY) {
            mProxy.setAlpha(alpha);
        } else {
            super.setAlpha(alpha);
        }
    }
    public float getTranslationX() {
        if (AnimatorProxy.NEEDS_PROXY) {
            return mProxy.getTranslationX();
        } else {
            return super.getTranslationX();
        }
    }
    public void setTranslationX(float translationX) {
        if (AnimatorProxy.NEEDS_PROXY) {
            mProxy.setTranslationX(translationX);
        } else {
            super.setTranslationX(translationX);
        }
    }

}


public final class AnimatorProxy extends Animation {
public static final boolean NEEDS_PROXY = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;


private static final WeakHashMap<View, AnimatorProxy> PROXIES = new WeakHashMap<View, AnimatorProxy>();


public static AnimatorProxy wrap(View view) {
AnimatorProxy proxy = PROXIES.get(view);
if (proxy == null) {
proxy = new AnimatorProxy(view);
PROXIES.put(view, proxy);
}
return proxy;
}


private final WeakReference<View> mView;


private float mAlpha = 1;
private float mScaleX = 1;
private float mScaleY = 1;
private float mTranslationX;
private float mTranslationY;


private final RectF mBefore = new RectF();
private final RectF mAfter = new RectF();
private final Matrix mTempMatrix = new Matrix();


private AnimatorProxy(View view) {
setDuration(0); // perform transformation immediately
setFillAfter(true); // persist transformation beyond duration
view.setAnimation(this);
mView = new WeakReference<View>(view);
}


public float getAlpha() {
return mAlpha;
}


public void setAlpha(float alpha) {
if (mAlpha != alpha) {
mAlpha = alpha;
View view = mView.get();
if (view != null) {
view.invalidate();
}
}
}


public float getScaleX() {
return mScaleX;
}


public void setScaleX(float scaleX) {
if (mScaleX != scaleX) {
prepareForUpdate();
mScaleX = scaleX;
invalidateAfterUpdate();
}
}


public float getScaleY() {
return mScaleY;
}


public void setScaleY(float scaleY) {
if (mScaleY != scaleY) {
prepareForUpdate();
mScaleY = scaleY;
invalidateAfterUpdate();
}
}


public int getScrollX() {
View view = mView.get();
if (view == null) {
return 0;
}
return view.getScrollX();
}


public void setScrollX(int value) {
View view = mView.get();
if (view != null) {
view.scrollTo(value, view.getScrollY());
}
}


public int getScrollY() {
View view = mView.get();
if (view == null) {
return 0;
}
return view.getScrollY();
}


public void setScrollY(int value) {
View view = mView.get();
if (view != null) {
view.scrollTo(view.getScrollY(), value);
}
}


public float getTranslationX() {
return mTranslationX;
}


public void setTranslationX(float translationX) {
if (mTranslationX != translationX) {
prepareForUpdate();
mTranslationX = translationX;
invalidateAfterUpdate();
}
}


public float getTranslationY() {
return mTranslationY;
}


public void setTranslationY(float translationY) {
if (mTranslationY != translationY) {
prepareForUpdate();
mTranslationY = translationY;
invalidateAfterUpdate();
}
}


private void prepareForUpdate() {
View view = mView.get();
if (view != null) {
computeRect(mBefore, view);
}
}


private void invalidateAfterUpdate() {
View view = mView.get();
if (view == null) {
return;
}
View parent = (View) view.getParent();
if (parent == null) {
return;
}


view.setAnimation(this);


final RectF after = mAfter;
computeRect(after, view);
after.union(mBefore);


parent.invalidate((int) FloatMath.floor(after.left), (int) FloatMath.floor(after.top), (int) FloatMath.ceil(after.right), (int) FloatMath.ceil(after.bottom));
}


private void computeRect(final RectF r, View view) {
// compute current rectangle according to matrix transformation
final float w = view.getWidth();
final float h = view.getHeight();


// use a rectangle at 0,0 to make sure we don't run into issues with
// scaling
r.set(0, 0, w, h);


final Matrix m = mTempMatrix;
m.reset();
transformMatrix(m, view);
mTempMatrix.mapRect(r);


r.offset(view.getLeft(), view.getTop());


// Straighten coords if rotations flipped them
if (r.right < r.left) {
final float f = r.right;
r.right = r.left;
r.left = f;
}
if (r.bottom < r.top) {
final float f = r.top;
r.top = r.bottom;
r.bottom = f;
}
}


private void transformMatrix(Matrix m, View view) {
final float w = view.getWidth();
final float h = view.getHeight();


final float sX = mScaleX;
final float sY = mScaleY;
if ((sX != 1.0f) || (sY != 1.0f)) {
final float deltaSX = ((sX * w) - w) / 2f;
final float deltaSY = ((sY * h) - h) / 2f;
m.postScale(sX, sY);
m.postTranslate(-deltaSX, -deltaSY);
}
m.postTranslate(mTranslationX, mTranslationY);
}


@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
View view = mView.get();
if (view != null) {
t.setAlpha(mAlpha);
transformMatrix(t.getMatrix(), view);
}
}


@Override
public void reset() {
/* Do nothing. */
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值