Android view property animation -
hello community wondering if me in following question. working on project need able move bitmap distance when touch it. (step 2 in snapshot) however,on reaching boundary image should wrapped other side shown in step 3.
i read property animator , how allows tweeting of views don't understand kind of layout should use. should use relativelayout or linearlayout? or should use canvas? how mask parent view (view b in snapshot) achieve view wrapping effect.
thank kindly,

import android.animation.animatorset; import android.animation.objectanimator; import android.content.context; import android.graphics.canvas; import android.graphics.matrix; import android.graphics.rectf; import android.util.attributeset; import android.view.motionevent; import android.view.view; import android.view.animation.accelerateinterpolator; import android.view.animation.decelerateinterpolator; import android.view.animation.linearinterpolator; import android.view.animation.overshootinterpolator; import android.widget.button; public class anticibutton extends button { private static final linearinterpolator slinearinterpolator = new linearinterpolator(); private static final decelerateinterpolator sdecelerator = new decelerateinterpolator(8); private static final accelerateinterpolator saccelerator = new accelerateinterpolator(); private static final overshootinterpolator sovershooter = new overshootinterpolator(); private static final decelerateinterpolator squickdecelerator = new decelerateinterpolator(); private float mskewx = 0; objectanimator downanim = null; boolean monleft = true; rectf mtemprect = new rectf(); public anticibutton(context context) { super(context); init(); } public anticibutton(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); init(); } public anticibutton(context context, attributeset attrs) { super(context, attrs); init(); } private void init() { setontouchlistener(mtouchlistener); setonclicklistener(new onclicklistener() { public void onclick(view v) { runclickanim(); } }); } @override public void draw(canvas canvas) { if (mskewx != 0) { canvas.translate(0, getheight()); canvas.skew(mskewx, 0); canvas.translate(0, -getheight()); } super.draw(canvas); } private void runpressanim() { downanim = objectanimator.offloat(this, "skewx", monleft ? .5f : -.5f); downanim.setduration(2500); downanim.setinterpolator(sdecelerator); downanim.start(); } private void runclickanim() { // anticipation objectanimator finishdownanim = null; if (downanim != null && downanim.isrunning()) { // finish skew animation downanim.cancel(); finishdownanim = objectanimator.offloat(this, "skewx", monleft ? .5f : -.5f); finishdownanim.setduration(150); finishdownanim.setinterpolator(squickdecelerator); } objectanimator moveanim = objectanimator.offloat(this, view.translation_x, monleft ? 400 : 0); moveanim.setinterpolator(slinearinterpolator); moveanim.setduration(150); objectanimator skewanim = objectanimator.offloat(this, "skewx", monleft ? -.5f : .5f); skewanim.setinterpolator(squickdecelerator); skewanim.setduration(100); // , wobble objectanimator wobbleanim = objectanimator.offloat(this, "skewx", 0); wobbleanim.setinterpolator(sovershooter); wobbleanim.setduration(150); animatorset set = new animatorset(); set.playsequentially(moveanim, skewanim, wobbleanim); if (finishdownanim != null) { set.play(finishdownanim).before(moveanim); } set.start(); monleft = !monleft; } private void runcancelanim() { if (downanim != null && downanim.isrunning()) { downanim.cancel(); objectanimator reverser = objectanimator.offloat(this, "skewx", 0); reverser.setduration(200); reverser.setinterpolator(saccelerator); reverser.start(); downanim = null; } } private view.ontouchlistener mtouchlistener = new view.ontouchlistener() { @override public boolean ontouch(view v, motionevent event) { switch (event.getaction()) { case motionevent.action_up: if (ispressed()) { performclick(); setpressed(false); break; } // no click: fall through; equivalent cancel event case motionevent.action_cancel: // run cancel animation in either case runcancelanim(); break; case motionevent.action_move: float x = event.getx(); float y = event.gety(); boolean isinside = (x > 0 && x < getwidth() && y > 0 && y < getheight()); if (ispressed() != isinside) { setpressed(isinside); } break; case motionevent.action_down: setpressed(true); runpressanim(); break; default: break; } return true; } }; public float getskewx() { return mskewx; } public void setskewx(float value) { if (value != mskewx) { mskewx = value; invalidate(); // force button redraw new skew value invalidateskewedbounds(); // invalidate appropriate area of parent } } private void invalidateskewedbounds() { if (mskewx != 0) { matrix matrix = new matrix(); matrix.setskew(-mskewx, 0); mtemprect.set(0, 0, getright(), getbottom()); matrix.maprect(mtemprect); mtemprect.offset(getleft() + gettranslationx(), gettop() + gettranslationy()); ((view) getparent()).invalidate((int) mtemprect.left, (int) mtemprect.top, (int) (mtemprect.right +.5f), (int) (mtemprect.bottom + .5f)); } } } add xml layout:
<view class="com.example.android.anticipation.anticibutton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="anticibutton"/> i hope help
Comments
Post a Comment