-
Notifications
You must be signed in to change notification settings - Fork 38
5. Event
While implementing interactions, there are times when you need to handle the user interface or various touch events.
Propose provides wide options of events pertaining to animations or motion cycles.
Events are divded into Animation, Motion and Propose, and you can implement listeners for each event.
You can obtain events of animators being played, and you can define events based on the situations: start, middle and the end.
- Obtain events for start, playing and the end of the animations.
- You can also get events of reverse animation supported by Propose.
- You can register
JwAnimatorListener
by using Animator.addListener().
animator.addListener(new JwAnimatorListener(){
public void onStart(Animator animation){
//This is called whenever the animation begins
}
public void onEnd(Animator animation){
//This is called whenever the animation finishes
}
public void onReverseStart(Animator animation){
//This is called whenever the reverse anmation begins
}
public void onReverseEnd(Animator animation){
//This is called whenever the reverse animation finishes
}
});
-
Example of 3D flipping
Now let's implement an animation for example: flipping card.
First, make flipping animations for front and back side, and then combine those two animations.
ObjectAnimator front = ObjectAnimator.ofFloat(flip_img, View.ROTATION_Y, 0,90);
front.setDuration(500);
ObjectAnimator back= ObjectAnimator.ofFloat(flip_img, View.ROTATION_Y, -90,0);
back.setDuration(500);
Propose propose = new Propose(this);
propose.motionRight.play(front).next(back); /** set right move Animator **/
propose.motionRight.setMotionDistance(200*Propose.getDensity(this)); /** set Drag Distance **/
flip_img.setOnTouchListener(propose); /** set touch listener **/
The reason why we didn't make single animation that rotates from 0˚ to 180˚ is that the image shows its reversed image when it's rotated 180 degrees.
Therefore, we split the animation into front and back, and make the animation for rotating from -90˚ to 0˚.
Result
You can get an event with JwAnimatorListener when the animation is reversed. With this listener, you can change the card image by adding the codes below.
front.addListener(new JwAnimatorListener() {
public void onStart(Animator arg0) {}
public void onEnd(Animator arg0) {
flip_img.setBackgroundResource(R.drawable.girl_background);
flip_img.setImageResource(R.drawable.girl);
}
public void onReverseStart(Animator arg0) {
flip_img.setBackgroundResource(R.drawable.boy_background);
flip_img.setImageResource(R.drawable.boy);
}
public void onReverseEnd(Animator arg0) {}
});
Result ( full source code )
-
You can use listeners which is given to Property Animation. Use AnimatorUpdateListener to check various values while playing.
paperAnim.addUpdateListener(new AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { //It's called every time the animation is played. } });
Note : You can also use all kinds of listeners provided by Property animations.
Motion comprises of combinations of animations, and you can get events for the cycle of whole animation
-
Obtain the event for start, middle, end of the Motion.
-
You can register
MotionListener
by using propose.motionRight.setOnMotionListener()
propose.motionRight.setOnMotionListener(new MotionListener() {
public void onStart(boolean isForward) {
//This is called whenever the motion starts
}
public void onScroll(long currDuration, long totalDuration, boolean isForward) {
//This is called whenever the motion is being played
}
public void onEnd(boolean isForward) {
//This is called whenever the motion is ended
}
});
- Alpha view Example You probably saw an interaction that background disappears as a view slides in or out.
You can implement this type of interaction onto the card flipping example with the code below.
propose.motionRight.setOnMotionListener(new MotionListener() {
public void onStart(boolean isForward) {}
public void onScroll(long currDuration, long totalDuration, boolean isForward) {
float alpha = (float)currDuration/totalDuration*0.8f;
findViewById(R.id.back_lyt).setAlpha(alpha);
}
public void onEnd(boolean isForward) {}
});
Result ( full source code )
Propose manages four motions of directions and it gets the events for the start, middle and the end of the motion.
-
Propose handles the status, start and the end of the Motion, and gets events for those situations.
-
You can register
ProposeListener
by using Propose.setOnProposeListener().
propose.setOnProposeListener(new ProposeListener() {
public void onStart() {
//This is called once when Propose has been started
}
public void onScroll(int Direction, long currDuration, long totalDuration) {
//This is called when a Motion of Propose is being played. You can categorize the motion depending on its direction
}
public void onEnd() {
//This is called once when all of Motions or animations are finished
}
});
-
Lion view Example
You can implement a lion view which moves freely by simply combining motions.
ObjectAnimator rightMove = ObjectAnimator.ofFloat(moving_lyt, View.TRANSLATION_X, 0,end);
ObjectAnimator rightDown = ObjectAnimator.ofFloat(moving_lyt, View.TRANSLATION_Y, 0,end);
rightMove.setInterpolator(null);
rightDown.setInterpolator(null);
rightMove.setDuration(1000);
rightDown.setDuration(1000);
Propose propose = new Propose(this);
propose.motionRight.play(rightMove);
propose.motionRight.setMotionDistance(end).enableTabUp(false); // right move option
propose.motionDown.play(rightDown);
propose.motionDown.setMotionDistance(end).enableSingleTabUp(false).enableFling(false).enableTabUp(false);
propose.motionRight.move(end/2);// center_horizontal lion
propose.motionDown.move(end/2); // center_vertical lion
moving_lyt.setOnTouchListener(propose);
Result ( full source code )
It couldn't be better if the lion shows running animation when it begins its movement.
Below is the code using ProposeListener for implementing the running animation when the lion moves.
final ObjectAnimator running = ObjectAnimator.ofFloat(lion_img,View.ROTATION, 0,-10,20,40,20);
running.setRepeatCount(ObjectAnimator.INFINITE);
running.setDuration(150);
propose.setOnProposeListener(new ProposeListener() {
public void onStart() {
running.start();
}
public void onScroll(int arg0, long arg1, long arg2) {}
public void onEnd() {
lion_img.setRotation(0f);
running.cancel();
}
});
Result ( full source code )
One of the most inconvenient features of Property animation is that we have to define the size. However, in Android, it's impossible to get size before a view is fully loaded. To handle this issue, we use view.onPost().
Propose provides MotionInitor. MotionInitor gets the size when a view is touched. This is very useful because it dynamically obtains the view size even if the view size is changing.
-
You can register
MotionInitor
by using Propose.setOnMotionInitor(). -
MotionInitor has touchDown,touchUp and this is called fist among events.
-
You can register a view by using MotionInitor.addParam("key",View), and get the dynamic information with getParam("key") of touchDown.
MotionInitor initor = new MotionInitor() {
public void touchDown(Propose propose) {
//You can get the view and its size by using getParam method
View lion_view = (View)getParam("lion");
int width = lion_view.getWidth();
//Set values such as Animation, Distance, etc.
propose.motionRight.setMotionDistance(width);
}
public void touchUp(Propose propose) {
//You can reset values when touchUp event is called if necessary.
}
};
//Register the view so that you can get its size when touchDown event is called(You can even register multiple views based on keys)
initor.addParam("lion", lion_view);
propose.setOnMotionInitor(initor);
.