I need to make an ImageView slide from left to right of the screen with a smooth animation (I want the ImageView to be visible during the transition) I tried with the following code:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
camion.animate()
.translationX(width)
.setDuration(2000)
.setInterpolator(new LinearInterpolator())
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//camion.setVisibility(View.GONE);
}
});
The ImageView moves but the animation is laggy and not smooth like I want to.
What am I doing wrong on the code?
Creating this kind of tween animation is simple. Just follow the steps,
Step 1
Create a directory anim inside the res directory and put this as slide.xml
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillAfter="true">
<translate
android:fromXDelta="0%p"
android:toXDelta="75%p"
android:duration="800" />
</set>
You can obviously customize the animation by changing the two attributes fromXDelta and toXDelta. The %p refers to with respect to the parent which simply means that it will move the image 75% with respect to the parent.
Step 2
// Refer the ImageView like this
imageView = (ImageView) findViewById(R.id.img);
// Load the animation like this
animSlide = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.slide);
// Start the animation like this
imageView.startAnimation(animSlide);
You can also setInterpolator() and setListeners() if you want to. I haven't shown them here to keep it simple. If you need, just let me know.
NOTE
As you have mentioned repeatedly, that you are experiencing a laggy animation. I have tested this animation on 3 real devices and 2 emulators and the animation was buttery smooth on all of them. Tested on low end devices like Moto E to high end devices like Nexus 5 and Galaxy S6.
If you still have a lag running this code, then the test device must be the reason. The code is perfect.
UPDATE
I just checked on my Moto G running on Lollipop too, the animation is running smoothly. This is a very small and light-weight animation, and should never be laggy. If you are still getting a lag, then it must be the device you are testing, or some other piece of code on that Activity making the UI slow or unresponsive.
Try to check which one is applicable to you,
I have tested on a total of 6 devices now with no lag at all. So, you can be rest assured that your production app will not have any lag, it can be your device which is slow
If you are doing some heavy operations like accessing the file system, database, or any other heavy operation, it must be slowing down the UI thread and you are loosing frames. Try to use AsyncTask for these heavy operations
Try this. It will animate the imageview.
ImageView img_animation = (ImageView) findViewById(R.id.img_animation);
Display display = getWindowManager().getDefaultDisplay();
float width = display.getWidth();
TranslateAnimation animation = new TranslateAnimation(0, width - 50, 0, 0); // new TranslateAnimation(xFrom,xTo, yFrom,yTo)
animation.setDuration(1000); // animation duration
animation.setRepeatCount(5); // animation repeat count
animation.setRepeatMode(2); // repeat animation (left to right, right to
// left )
// animation.setFillAfter(true);
img_animation.startAnimation(animation); // start animation
TranslateAnimation animate = new TranslateAnimation(0, -view.getWidth(), 0, 0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
Hope this works for u
animation.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Animation" >
<ImageView
android:id="#+id/img_animation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="42dp"
android:src="#drawable/emo_im_laughing" />
</RelativeLayout>
Animation.java
import android.os.Bundle;
import android.app.Activity;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
public class Animation extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.);
ImageView img_animation = (ImageView) findViewById(R.id.img_animation);
TranslateAnimation animation = new TranslateAnimation(0.0f, 400.0f,
0.0f, 0.0f);
animation.setDuration(5000);
animation.setRepeatCount(5);
animation.setRepeatMode(2);
animation.setFillAfter(true);
img_animation.startAnimation(animation);
}
}
try the code below
TranslateAnimation animation = new TranslateAnimation(0.0f, 0.0f, 0.0f, 1500.0f); // new TranslateAnimation (float fromXDelta,float toXDelta, float fromYDelta, float toYDelta)
animation.setDuration(2000); // animation duration
animation.setRepeatCount(1); // animation repeat count if u repeat only once set to 1 if u don't repeat set to 0
animation.setFillAfter(false);
your_view .startAnimation(animation);//your_view for mine is imageView
public class MainActivity extends Activity {
int windowwidth;
int windowheight;
private LayoutParams layoutParams;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
windowwidth = getWindowManager().getDefaultDisplay().getWidth();
windowheight = getWindowManager().getDefaultDisplay().getHeight();
final ImageView img = (ImageView) findViewById(R.id.imageView1);
img.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
LayoutParams layoutParams = (LayoutParams) img
.getLayoutParams();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int x_cord = (int) event.getRawX();
int y_cord = (int) event.getRawY();
if (x_cord > windowwidth) {
x_cord = windowwidth;
}
if (y_cord > windowheight) {
y_cord = windowheight;
}
layoutParams.leftMargin = x_cord - 25;
layoutParams.topMargin = y_cord - 75;
img.setLayoutParams(layoutParams);
break;
default:
break;
}
return true;
}
});
}
}
To Move imageview
from Right to Left Using #Aritra Roy Answer.
Use this code
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillAfter="true">
<translate
android:fromXDelta="75%p"
android:toXDelta="0%p"
android:duration="100000" />
</set>
Now we have MotionLayout try to use that for very clean and smooth sliding animation.
Related
In my app, I have a button to show a drop-down menu, inside of that menu we have some options, one of this is "flip A coin",
the purpose of this option is to flip a coin easy animation, that animation appears inside a textView, and show a head-side or a tail-side of a coin instead of the text in the textView.
I have two problems:
The animation doesn't work how I want, it should appear in 1 second a coin instead of the text inside the textView, it stays there and after 2 seconds he disappears, but after the disappearance, the coin image come back inside the textView, it shouldn't reappear.
This is not a real question for a problem but more an optional question like "you know how to do that?". I 'don't know how to create a flip animation with a coin multiple rotations.
XML drop down menu:
<item
android:id="#+id/flipacoin"
android:title="#string/flipACoin" />
<item
android:id="#+id/rolladice"
android:title="#string/rollADice" />
<item
android:id="#+id/imagebackground"
android:title="#string/changeImage" />
JAVA code that calls the animation function:
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.flipacoin:
flipACoin();
return true;
case R.id.rolladice:
Toast.makeText(this,"TODO roll a dice",Toast.LENGTH_SHORT).show();
return true;
case R.id.imagebackground:
Toast.makeText(this,"TODO image background",Toast.LENGTH_SHORT).show();
return true;
default:
return false;
}
}
JAVA animation function:
public void flipACoin(){
coin.setText(null); //this is for remove the text inside the textView
coin.setBackground(RANDOM.nextFloat() > 0.5f ? getResources().getDrawable(R.drawable.tails) : getResources().getDrawable(R.drawable.heads));
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(1000);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setStartOffset(2000);
fadeOut.setDuration(1000);
AnimationSet animation = new AnimationSet(false);
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
coin.setAnimation(animation);
}
When You set background at the beginning it just stays after animation. To set back text and background to null You can add Animation listener. Below is sample application which does it:
public class MainActivity extends AppCompatActivity
{
TextView coin;
Random RANDOM;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RANDOM = new Random();
coin = findViewById(R.id.coin);
(findViewById(R.id.click)).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
flipACoin();
}
});
}
public void flipACoin()
{
coin.setText(null);
coin.setBackground(ResourcesCompat.getDrawable(getResources(),
RANDOM.nextFloat() > 0.5f ? R.drawable.ic_launcher_background : R.drawable.ic_launcher_foreground,
null
));
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(1000);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setStartOffset(2000);
fadeOut.setDuration(1000);
AnimationSet animation = new AnimationSet(false);
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
// listener, it will execute function when animation starts/ends/repeats
animation.setAnimationListener(new Animation.AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
Log.d("MyTag", "onAnimationStart:");
}
#Override
public void onAnimationEnd(Animation animation) // when animation ends, set text and background to null
{
Log.d("MyTag", "onAnimationEnd:");
coin.setBackground(null);
coin.setText("Default");
}
#Override
public void onAnimationRepeat(Animation animation)
{
Log.d("MyTag", "onAnimationRepeat:");
}
});
coin.setAnimation(animation);
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="#+id/click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click"
/>
<TextView
android:id="#+id/coin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Default"
/>
</androidx.appcompat.widget.LinearLayoutCompat>
I'm using a RotateAnimation to rotate an AppCompatButton, used as a toolbar button, and i want to change its background while is rotating.
I didn't find any useful topic so far.
Here's my code :
AppCompatButton mBtn = (AppCompatButton) view.findViewById(R.id.search_btn);
Animation mRotateAnimation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.rotation);
mBtn.setAnimation(mRotateAnimation);
mBtn.startAnimation(mRotateAnimation);
rotation.xml:
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:duration="600" />
I want to get a smooth background change between the beginning and the end of animation. Any useful resource link or code would be amazing. Thank you guys!
You should add another ValueAnimation to your view.
AppCompatButton mBtn = (AppCompatButton) view.findViewById(R.id.search_btn);
Animation mRotateAnimation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.rotation);
mBtn.setAnimation(mRotateAnimation);
mBtn.startAnimation(mRotateAnimation);
int colorFrom = getResources().getColor(R.color.red);
int colorTo = getResources().getColor(R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(600);
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animator) {
mBtn.setBackgroundColor((int) animator.getAnimatedValue());
}
});
colorAnimation.start();
I have an image set in an ImageView and I want to animate it such a way that initially nothing is displayed on the screen and the the image enters from left and go towards right and finally fill the screen
In the code that i examine the image enters from left but doesn't fill the screen and left blank behind itself
ObjectAnimator transAnimation=
ObjectAnimator.ofFloat(imageView,"translationX",-100,100);
transAnimation.setDuration(3000);//set duration
transAnimation.start();//start animation
The code for animation that you posted seems to be working fine. The problem that you have is with imageview itself and the place it takes over your screen.
You said that your imageview is not taking full space and leaving blank space behind it,
so to fix it simply make your imageview width = match_parent. and if it still doesn't work then add scaleType=centerCrop
UPDATE:
Add this code to your onCreate()
imageView.post(new Runnable() {
#Override
public void run() {
startImageAnimation();
}
});
private void startImageAnimation() {
ObjectAnimator animation = ObjectAnimator.ofFloat(imageView, "translationX",-(imageView.getWidth()), 0);
animation.setDuration(1100);
animation.start();
}
step 1: create below left_to_right_anim file in anim directory of res
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillAfter="true">
<translate
android:fromXDelta="0%p"
android:toXDelta="75%p"
android:duration="800" />
</set>
step 2:
//your image view
imageView = (ImageView) findViewById(R.id.img);
//name of animation from anim directory
animSlide = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.left_to_right_anim);
// Start the animation like this
imageView.startAnimation(animSlide);
step 3:
now calculate time of animation and when your imageview animate at right side stop it and set it into your screen.
to achieve this you can user handler when you start your animation.
Thread's run() method is used to get time of your animation.
thanks ;)
What about using TransistionManager?
val slideRight= Slide()
slideRight.slideEdge = Gravity.RIGHT
slideRight.mode = Slide.MODE_IN
slideRight.addTarget(logoImageView)
slideRight.duration = ANIMATION_DURATION
TransitionManager.beginDelayedTransition(parentContainer, slideRight)
logoImageView.visibility = VISIBLE
It is snippet from my working code in Kotlin
Also you can use TransitionSet to combine animations
i am trying to move image view from top of screen to center or middle of the screen using translation animation i.e when activity is started image view is start moving from top of screen to middle or center of screen where top of image view space and bottom of image view space shows equal on screen exactly as we do like in relative layout use tag center In Parent true in xml file of layout. generally we find these kind of animation in facebook and whatsapp application they have used for images to translate or move image view animation.i have tried lots of SO question and answer also googling but not find proper solution. what i have done so far as following.Please help me to solve these issue.thanks.
public class MainActivity extends AppCompatActivity {
ImageView imageview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageview = (ImageView) findViewById(R.id.imagview);
RelativeLayout root = (RelativeLayout) findViewById(R.id.rel);
TranslateAnimation anim = new TranslateAnimation(0, 0, 0, 50);
anim.setInterpolator((new AccelerateDecelerateInterpolator()));
anim.setAnimationListener(new MyAnimationListener());
anim.setDuration(500);
anim.setFillAfter(true);
imageview.startAnimation(anim);
}
});
}
Assuming you have a View which is position on top left corner of screen, we want to animate it to the centre of screen.
Layout file:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/root">
<View
android:id="#+id/animated_view"
android:layout_width="50dp"
android:background="#6eed57"
android:layout_height="50dp"/>
</FrameLayout>
In onCreate():
final View root = findViewById(R.id.root);
final View animatedView = findViewById(R.id.animated_view);
root.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
animatedView.animate()
.translationX((root.getWidth() - animatedView.getWidth()) / 2)
.translationY((root.getHeight() - animatedView.getHeight()) / 2)
.setInterpolator(new AccelerateInterpolator())
.setDuration(500);
}
});
Result:
You don't start an animation in onCreate() because the screen isn't completely visible for the user. You also don't need to get root view if your root view uses the entire area of the screen.
boolean hasAnimationStarted;
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && !hasAnimationStarted) {
hasAnimationStarted=true;
DisplayMetrics metrics = getResources().getDisplayMetrics();
ObjectAnimator translationY = ObjectAnimator.ofFloat(imageview, "y", metrics.heightPixels / 2 - imageview.getHeight() / 2); // metrics.heightPixels or root.getHeight()
translationY.setDuration(500);
translationY.start();
}
}
I have the following xml:
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator">
<translate
android:fromXDelta="0%p"
android:toXDelta="30%p"
android:duration="600">
</translate>
</set>
and this class:
switch_bg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!isChecked) {
Animation animation = android.view.animation.AnimationUtils
.loadAnimation(AppService.getAppContext(),
com.waze.R.anim.slide_to_right);
animation.setInterpolator(new AccelerateInterpolator());
animation.setFillAfter(true);
boxImage_left.startAnimation(animation);
AlphaAnimation alpha = new AlphaAnimation(1, 0);
alpha.setDuration(1000);
alpha.setInterpolator(new AccelerateInterpolator());
alpha.setFillAfter(true);
vImage_left.startAnimation(alpha);
} else {
Animation animation = android.view.animation.AnimationUtils
.loadAnimation(AppService.getAppContext(),
com.waze.R.anim.slide_to_left);
animation.setInterpolator(new AccelerateInterpolator());
animation.setFillAfter(true);
boxImage_left.startAnimation(animation);
AlphaAnimation alpha = new AlphaAnimation(0, 1);
alpha.setDuration(1000);
alpha.setInterpolator(new AccelerateInterpolator());
alpha.setFillAfter(true);
vImage_left.startAnimation(alpha);
}
TransitionDrawable transition = (TransitionDrawable) switch_bg
.getBackground();
transition.reverseTransition(TRANSITION_TIME);
isChecked = !isChecked;
}
});
}
when I move the box right-to-left it stays there after animation,
but after animation left-to-right it returns to origin position on the left.
How come?
I use alpha.setFillAfter(true); on both cases.
update
strangely if I cancel the setFillAfter for alpha animation,
the sliding transition stays OK at the end. How come? these are two different transition objects.
As I understand it you need only a single tween animation at a time on a view; you should be able to express the alpha animation in the xml too. This would solve your problem; should be reliable across all android versions (I'm not sure your current solution always looks right); and simplify the code.