public void animateScreenOn() {
CellLayout layout = (CellLayout) getChildAt(getCurrentPage());
if (layout != null) {
int count = layout.getPageChildCount();
for (int i = count-1; i>=0; i--) {
View v = layout.getPageChild(i);
v.setScaleX(0.95f);
v.setScaleY(0.95f);
AnimatorSet set = new AnimatorSet();
ObjectAnimator animation1 = LauncherAnimUtils.ofPropertyValuesHolder(v,
PropertyValuesHolder.ofFloat("scaleX", 1.0f));
animation1.setDuration(1000L);
animation1.setInterpolator(new BounceInterpolator());
ObjectAnimator animation2 = LauncherAnimUtils.ofPropertyValuesHolder(v,
PropertyValuesHolder.ofFloat("scaleY", 1.0f));
animation2.setDuration(500L);
animation2.setInterpolator(new BounceInterpolator());
List<Animator> items = new ArrayList<Animator>();
items.add(animation1);
items.add(animation2);
set.playTogether(items);
set.setStartDelay((count-1-i)*100L);
set.start();
}
}
}
this code have an issue. the time of this code cost is different on different devices, some is ok, but some will be too short, so i need to change animate time depend on device refresh rate. anyone can tell me how to get it from android code, 3X!
Related
I have a case where I have 2 edittext email and password. When any one gets focus say email the hint moves up and becomes the heading. In this animation i translate the textview(hint) up and at the same time scale it down to 0.8f.
At the same time the second textview say password looses focus, if its still empty i want to reverse the animation and put back the heading as hint.
To sum up hint moves up as heading and gets back to hint position if the edittext remains empty.
I have two different animation set for both the editText views, they work well individually but on parallel execution one of them doesnt show up instead the hint becomes invisible.
My code is as follows :
email.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
if(b && emailAnimated==false){
Log.d("email1", "called");
AnimationSet animSet = new AnimationSet(true);
animSet.setFillAfter(true);
animSet.setFillEnabled(true);
animSet.setDuration(800);
TranslateAnimation translate = new TranslateAnimation(0, 0, 0, -60);
animSet.addAnimation(translate);
ScaleAnimation scale = new ScaleAnimation(1f, 0.8f, 1f, 0.8f);
animSet.addAnimation(scale);
emailText.startAnimation(animSet);
emailAnimated=true;
}else if(emailAnimated==true)
{
Log.d("email2", "called");
AnimationSet animSet = new AnimationSet(true);
animSet.setFillAfter(true);
animSet.setFillEnabled(true);
animSet.setDuration(800);
TranslateAnimation translate = new TranslateAnimation(0, 0, 0, -60);
animSet.addAnimation(translate);
ScaleAnimation scale = new ScaleAnimation(1f, 0.8f, 1f, 0.8f);
animSet.addAnimation(scale);
//Reverse the animation if losses focus
animSet.setInterpolator(new ReverseInterpolator());
emailText.startAnimation(animSet);
emailAnimated=false;
}
}
});
password.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
if(b && passwordAnimated==false){
Log.d("pass1", "called");
AnimationSet animSet = new AnimationSet(true);
animSet.setFillAfter(true);
animSet.setFillEnabled(true);
animSet.setDuration(800);
TranslateAnimation translate = new TranslateAnimation(0, 0, 0, -60);
animSet.addAnimation(translate);
ScaleAnimation scale = new ScaleAnimation(1f, 0.8f, 1f, 0.8f);
animSet.addAnimation(scale);
passwordText.startAnimation(animSet);
passwordAnimated=true;
}
else if(passwordAnimated==true)
{
Log.d("pass2", "called");
AnimationSet animSet = new AnimationSet(true);
animSet.setFillAfter(true);
animSet.setFillEnabled(true);
animSet.setDuration(800);
TranslateAnimation translate = new TranslateAnimation(0, 0, 0, -60);
animSet.addAnimation(translate);
ScaleAnimation scale = new ScaleAnimation(1f, 0.8f, 1f, 0.8f);
animSet.addAnimation(scale);
animSet.setInterpolator(new ReverseInterpolator());
passwordText.startAnimation(animSet);
passwordAnimated=false;
}
}
});
Just to make it more understandable, else if condition of email will be called whenever if condition of password is true and vies versa and thats how 2 animation sets are called.
You can try to set the layer type of the two EditTexts to hardware while animating.
animSet.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart( Animation animation ) {
emailText.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
#Override
public void onAnimationRepeat( Animation animation ) {
}
#Override
public void onAnimationEnd( Animation animation ) {
emailText.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
I have simple animation that moves the object in Y axis. I want change the behavior for the REVERSE.
//My Code:
ImageView iv = ... //my view
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "y", 300);
oa.setDuration(100);
oa.setRepeatCount(1);
oa.setRepeatMode(ValueAnimator.REVERSE);
oa.start();
You cannot change the behavior of the reverse mode. Instead, you will need to create an AnimatorSet and play them sequentially.
ImageView iv = ... //my view
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "y", 300);
oa.setDuration(100);
ObjectAnimator oa2 = ObjectAnimator.ofFloat(/* code here */)
// Add any other code for oa2
AnimatorSet set = new AnimatorSet();
set.playSequentially(oa, oa2);
set.start()
int imgSize = 30;
final ShapeDrawable redDot = new ShapeDrawable(new OvalShape());
redDot.getPaint().setColor(Color.RED);
redDot.setIntrinsicHeight(imgSize);
redDot.setIntrinsicWidth(imgSize);
final Bitmap bitmap = Bitmap.createBitmap(imgSize, imgSize, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
redDot.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
redDot.draw(canvas);
ImageView imgAnimArea = new ImageView(getActivity());
imgAnimArea.setImageBitmap(bitmap);
imgAnimArea.setScaleType(ImageView.ScaleType.CENTER);
animationsView.addView(imgAnimArea);
final AnimationSet animSetRedDot = new AnimationSet(true);
// animSetRedDot.setFillAfter(true);
// animSetRedDot.setFillEnabled(true);
Animation aniRepeatFadeIn = null;
Animation aniRepatFadeOut = null;
// fade out
aniRepatFadeOut = new AlphaAnimation(1, 0);
aniRepatFadeOut.setStartOffset(3000);
aniRepatFadeOut.setDuration(300);
animSetRedDot.addAnimation(aniRepatFadeOut);
// fade out animation works only if remove this part
aniRepeatFadeIn = new AlphaAnimation(0, 1);
aniRepeatFadeIn.setStartOffset(6000);
aniRepeatFadeIn.setDuration(300);
animSetRedDot.addAnimation(aniRepeatFadeIn);
imgAnimArea.startAnimation(animSetRedDot);
Its simple code (at least the animation part) but has very strange behavior. Basically before animation it creates a shape (small red circle) converts it to a bitmap and adds it to animationsView(FrameLayout) as ImageView's source (imgAnimArea).
So my red dot fades out but never appears back and it works only in case the fade in part is removed even thou the fade in fires later than fade out. I was trying also to set fade out to .5f instead of 0. In this case it fades out a half of visibility.
Also I had tried to animate animationsView but result is the same - only fade out part works if no fade in part added and if fade in part added then whole animation doesn't work at all.
I could see the shape with no animation added at all. Also I could see it after animation finishes in any case. Enabling or disabling FillAfter has no effect at all.
So the question is whats wrong here? Why fade in animation does not work? Why the whole animation does not work if fade in animation added?
here you have two ways how to do it (see if statement inside onClick() method)
one is preferred one not, the choice is yours
final TextView tv = new TextView(this);
tv.setText("click me");
tv.setTextSize(40);
tv.setTextColor(0xffeeeeee);
tv.setBackgroundColor(0xaa00ff00);
tv.setGravity(Gravity.CENTER);
OnClickListener l = new OnClickListener() {
#Override
public void onClick(View v) {
Animation a;
boolean preferred = true;
if (preferred) {
Log.d(TAG, "onClick using custom Interpolator, preferred way");
// this is a preferred way: custom Interpolator
a = new AlphaAnimation(0, 1);
Interpolator i = new Interpolator() {
#Override
public float getInterpolation(float input) {
return (float) (1 - Math.sin(input * Math.PI));
}
};
a.setInterpolator(i);
} else {
Log.d(TAG, "onClick using AnimationSet, NOT preferred way");
AnimationSet set = new AnimationSet(true);
AlphaAnimation alpha0 = new AlphaAnimation(1, 0);
alpha0.setDuration(1000);
alpha0.setFillEnabled(true);
alpha0.setFillBefore(false);
alpha0.setFillAfter(false);
set.addAnimation(alpha0);
AlphaAnimation alpha1 = new AlphaAnimation(0, 1);
alpha1.setDuration(1000);
alpha1.setFillEnabled(true);
alpha1.setFillBefore(false);
alpha1.setFillAfter(false);
alpha1.setStartOffset(1000);
set.addAnimation(alpha1);
a = set;
}
a.setDuration(2000);
tv.startAnimation(a);
}
};
tv.setOnClickListener(l);
setContentView(tv);
I want to animate the change in the padding of a view. The resting place of the translation animation is the same as the padding I want to apply.
TranslateAnimation moveleft = new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, PADDING, Animation.ABSOLUTE,
0.0f, Animation.ABSOLUTE, 0.0f);
moveLeft.setDuration(500);
moveLeft.setFillAfter(true);
This starts the view's animation then sets the padding. This doesn't exactly work because it cause a graphical glitch.
v.startAnimation(moveleft);
v.setPadding(PADDING, 0, 0,0);
Use ValueAnimator, its really simple and unclutter
say,
we have to change right padding to _20dp where as left, top and bottom padding are _6dp, _6dp and 0 respectively.
ofInt() is varagrs type. the value we have to animate is pass in it as KeyValue pair (arg1 = current value, arg2 = target value,............)
Here we go,
ValueAnimator animator = ValueAnimator.ofInt(view.getPaddingRight(), _20dp);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator){
view.setPadding(_6dp, _6dp, (Integer) valueAnimator.getAnimatedValue(), 0);
}
});
animator.setDuration(200);
animator.start();
Instead of setting your padding right away, why not try an animation listener to set the padding after the animation has completed?
v.setAnimationListener(new Animation.AnimationListener() {
...
#Override
public void onAnimationEnd(){
v.setPadding(PADDING, 0, 0,0);
}
...
});
v.startAnimation(moveleft);
Here is how to animate setPadding in Kotlin:
private fun setPaddingWithAnimation() {
val paddingDp: Int = 20
val density: Float = requireActivity().getResources().getDisplayMetrics().density
val paddingPixel: Int = (paddingDp * density).toInt()
val animator = ValueAnimator.ofInt(recyclerItems.paddingRight, paddingPixel)
animator.addUpdateListener { valueAnimator -> binding.recyclerHealthTips.recyclerHealthTips.setPadding(
paddingPixel, 0, valueAnimator.animatedValue as Int, 0) }
animator.duration = 500
animator.start()
}
I am creating an animation where my image will translate to a different spot on the screen and then fade in gradually. I completed the translation part(see below) but now when I start the fade in animation it disappears for the duration and then reapears after. I want to show the image being faded in gradually....Any ideas why this is happening?
public static int moveTwo(AnimationListener activity, View apa, int animationmove)
Log.v("MOVETWO", "Started move2");
AnimationSet picMov2 = new AnimationSet(true);
picMov2.setAnimationListener(activity);
RotateAnimation rotate2 = new RotateAnimation(0, 0,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
// rotate1.setStartOffset(50);
rotate2.setDuration(2000);
picMov2.addAnimation(rotate2);
TranslateAnimation trans2 = new TranslateAnimation(-200, -400, 0, 0);
trans2.setDuration(2000);
picMov2.setFillAfter(true);
picMov2.addAnimation(trans2);
apa.startAnimation(picMov2);
animationmove = 3;
return animationmove;
public static int moveThree(AnimationListener activity, View apa, int animationmove)
AlphaAnimation fadein = new AlphaAnimation((float) 0.3, 1);//HERE THE IMAGE IS DISAPPEARING
fadein.setAnimationListener(activity);
fadein.setDuration(2000);
fadein.setFillAfter(true);
apa.startAnimation(fadein);
animationmove=4;
return animationmove;
Just needed to create a translate action in the same place so it doesn't go back to its original position
public static int moveThree(AnimationListener activity, View apa, int animationmove)
{
Log.v("MOVETHREE", "Started move3");
AnimationSet picMov3 = new AnimationSet(true);
picMov3.setAnimationListener(activity);
AlphaAnimation fadein = new AlphaAnimation((float) 0.4, 1);
// rotate1.setStartOffset(50);
fadein.setDuration(duration);
picMov3.addAnimation(fadein);
TranslateAnimation trans1 = new TranslateAnimation(-400, -400, 0, 0);
trans1.setDuration(duration);
picMov3.setFillAfter(true);
picMov3.addAnimation(trans1);
apa.startAnimation(picMov3);