This question already has an answer here:
image is playing an animation and the image is clickable
(1 answer)
Closed 10 years ago.
I've made a simple animation for an image and I set the event OnClick on the image to make a toast. The problem is that I made the image started doing the animation on the onCreate and I made set the image to be clicked and fire the toast but the problem is that the image isn't clickable, but if I press on the original position of the image, the toast is started (the image is not moving with the animation)
thx for your help
this is the animation code in anim folder (translate.xml)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<translate
android:fromXDelta="-80%p"
android:toXDelta="80%p"
android:duration="20000"
android:repeatCount="100"
android:repeatMode="restart"
/>
</set>
and this is the Activity Class
package com.example.animatest;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
private ImageView image01;
private long aefe;
private ImageView image1;
private ImageView image2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image01 = (ImageView) findViewById(R.id.imageView1);
final Animation animTranslate1 = AnimationUtils.loadAnimation(this,
R.anim.translate);
image01.startAnimation(animTranslate1);
image01.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "hello", Toast.LENGTH_SHORT)
.show();
}
});
}
}
During the entire animation, your view remains at the old location (location when the animation just started). It is just drawn in another spot. You'd have to move your animated view after your animation ends:
Register a listener to your animation.
http://developer.android.com/reference/android/view/animation/Animation.AnimationListener.html
In your onAnimationEnd implementation, modify your Activity's layout so that it resembles the final state/layout of your animation.
Update after your comment:
The only way I see of doing this is by creating your own custom Animation in Java code and implementing your custom Animation's 'protected void applyTransformation(float interpolatedTime, Transformation t)' method. For example, in our app we have an animation that actually moves a View around instead of just drawing it at a different location. E.g. below is an example of an Animation that increases or decreases the actual height of a View:
public class ViewHeightAnimation extends Animation {
private final View view;
private final float diffHeight;
private final int startHeight;
public ViewHeightAnimation(View view, float diffHeight, int startHeight) {
this.view = view;
this.diffHeight = diffHeight;
this.startHeight = startHeight;
setDuration(200);
setInterpolator(new AccelerateDecelerateInterpolator());
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
android.view.ViewGroup.MarginLayoutParams layoutParams = (android.view.ViewGroup.MarginLayoutParams)view.getLayoutParams();
layoutParams.height = Math.round(startHeight + (diffHeight * interpolatedTime));
view.setLayoutParams(layoutParams);
}
#Override
public boolean willChangeBounds() {
return true;
}
}
Your Animation would be different, but would be using the 'getLayoutParams()' and 'setLayoutParams()' as well to modify the View's (ImageView's) position and change layoutParams.topMargin and layoutParams.leftMargin appropriately.
If you are not concerned about Android 2.x or lower, using the ObjectAnimator (3.0 or higher) or ViewPropertyAnimator (3.1 or higher) is a better solution, as was mentioned in other answer earlier.
Let me know if this helps you.
try like this:
final Animation animTranslate1 = AnimationUtils.loadAnimation(this,R.anim.translate);
animTranslate1.setFillAfter(true);
image01.startAnimation(animTranslate1);
If that does not work then you'll have to use the newer Property Animation framework (which was pointed out in the answer to your previous duplicate question)
See here to learn about it
The way you animate your imageView is only move its appearance, so actually your imageView is still at the old position. There's not an easy way to do what you want, with this type animations. You should consider to use ObjectAnimators ...
Related
everyone. I'm sort of new to android development and I've ran into a bit of a problem.
As is it's written in the title, I'm trying to create an app in which a button moves to a random location on the screen every time it is clicked. A sort of a "runaway button" thingy.
Here is the XML code.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:background="#color/colorPrimary"
tools:context="com.example.a4ld.MainActivity">
<Button
android:id="#+id/button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button" />
</LinearLayout>
And here is the main activity code.
At first the solution seems pretty simple. Just move the random values into the onClick method. That way new coordinates would get generated every time the button is clicked. But whenever I do that the animationListener class cannot reach those values and move the view accordingly so that the clickable area of the button would match its position on the screen.
package com.example.a4ld;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.LinearLayout;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get display size.
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
final int height = displayMetrics.heightPixels;
final int width = displayMetrics.widthPixels;
//generates random values within display size range.
//doesn't work as intended. the button still goes out of bounds sometimes.
Random n = new Random();
final int height01 = n.nextInt(height - 0) + 0;
Random m = new Random();
final int width01 = m.nextInt(width - 0) + 0;
final Button button01 = (Button) findViewById(R.id.button01);
button01.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//animates button movement.
TranslateAnimation animation01 = new TranslateAnimation(0, width01, 0, height01);
animation01.setDuration(500);
animation01.setAnimationListener(new animationListener());
button01.startAnimation(animation01);
}
class animationListener implements Animation.AnimationListener {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
//moves the view(probably) to match the new button position.
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(button01.getWidth(), button01.getHeight());
layoutParams.setMargins(width01, height01, 0, 0);
button01.setLayoutParams(layoutParams);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
}
});
}
}
Pardon me for any mistakes. This is my first time asking for help here.
Every bit of help will be greatly appreciated and thank you for your time.
You should rather use ViewPropertyAnimator. This animates the view to its future position and you don't need to force any layout params on the view after the animation ends. And it's rather simple.
myView.animate().x(50f).y(100f);
myView.animate().translateX(pixelInScreen)
Note: This pixel is not relative to the view. This pixel is the pixel position in the screen.
I encounter a problem to which i got no answer to google at all. So i got an image which is 740x610 pixels, 282.73kb, 32bit color.I simply apply the simplest rotation animation upon this image, thats how the boss wants.The xml code for animation is the next.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<rotate
android:duration="5000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="360" />
</set>
this is how i apply animation inside the code.(The target to be animated is an ImageView)
levelUpLightingRight.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_right));
Anyways, whenever the animation starts rotation lagging the worst way it could be. I tried to make image smaller, and BOOM, that worked, the animation is never being smoother. Problems are the next. I can't resize image no way,because if i do so,image get rectangle around it and its ugly,so the designer made it look right so i stuck up with this image size. Animation applied to this image lagging. I can't make image smaller because that won't be as boss wants the UI to be seen so i stuck in the point where animation purely lags like i never seen before in my development experience. What i tried so far.
1-applying required parameters to manifest.xml like ...android:hardwareAccelerated="true",android:largeHeap="true"
2-Trying with different types of animations like ValueAnimatior,ObjectAnimator,AnimatorSet and so on.
3-Using third part libraries like 2d renderings.
Ofcourse nothing helped me out.Im thinking of applying animation inside surface view,but i don't see it coming to success..Anyway if anyone encounter such problems and do have solution,please share,or at least guide to right direction.Thank you before hand.
FULL CLASS CODE.
package com.vegasslots.dialogs;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.vegasslots.R;
/**
* Created by vladimirarevhstayna on 12/24/15.
*/
public class LevelUpDialog extends DialogFragment implements View.OnClickListener {
private static final String TAG = "_LevelUpDialog";
private ImageView coin_1;
private ImageView coin_2;
private ImageView coin_3;
private ImageView coin_4;
private ImageView coin_5;
private ImageView coin_6;
private ImageView coin_7;
private ImageView coin_8;
private ImageView coin_9;
private ImageView coin_10;
private ImageView coin_11;
private ImageView coin_12;
private ImageView coin_13;
private ImageView coin_14;
private ImageView coin_15;
private CountDownTimer levelUpCountDownTimer;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//init our viewHolder of .
return inflater.inflate(R.layout.dialog_level_up_view, container);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final RelativeLayout levelUpLightingLeft = (RelativeLayout) view.findViewById(R.id.levelUpLighting_left);
RelativeLayout levelUpLightingRight = (RelativeLayout) view.findViewById(R.id.levelUpLighting_right);
coin_1 = (ImageView) view.findViewById(R.id.imageView8);
coin_2 = (ImageView) view.findViewById(R.id.imageView16);
coin_3 = (ImageView) view.findViewById(R.id.imageView7);
coin_4 = (ImageView) view.findViewById(R.id.imageView12);
coin_5 = (ImageView) view.findViewById(R.id.imageView10);
coin_6 = (ImageView) view.findViewById(R.id.imageView9);
coin_6 = (ImageView) view.findViewById(R.id.imageView9);
coin_7 = (ImageView) view.findViewById(R.id.imageView4);
coin_8 = (ImageView) view.findViewById(R.id.imageView15);
coin_9 = (ImageView) view.findViewById(R.id.imageView14);
coin_10 = (ImageView) view.findViewById(R.id.imageView5);
coin_11 = (ImageView) view.findViewById(R.id.imageView3);
coin_12 = (ImageView) view.findViewById(R.id.imageView5);
coin_13 = (ImageView) view.findViewById(R.id.imageView11);
coin_14 = (ImageView) view.findViewById(R.id.imageView6);
coin_15 = (ImageView) view.findViewById(R.id.imageView13);
view.findViewById(R.id.mainLayout).setOnClickListener(this);
//
levelUpLightingLeft.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_left));
levelUpLightingRight.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_right));
AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(coin_1, "translationX", 180, -90),
ObjectAnimator.ofFloat(coin_1, "translationY", 180, -90)
);
set.setDuration(200).start();
levelUpCountDownTimer = new CountDownTimer(4000, 4000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
Log.d(TAG, "ON FINISH");
if (isVisible()) {
dismiss();
}
}
}.start();
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
// getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#aa000000")));
// getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
}
#Override
public void onDestroyView() {
super.onDestroyView();
levelUpCountDownTimer.cancel();
}
#Override
public void onClick(View v) {
dismiss();
}
}
I reduce the animation duration to half and it worked for some reasons!
android:duration="500"
I'm trying to animate an ImageView using the ValueAnimator class. However, the official documentation for the ValueAnimator class does not contain enough details(at least, for beginners). I want the ImageView to move rightwards(translate animation) upon clicking a Button. I'm using the following code but without use.
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.Button;
import android.widget.ImageView;
import android.animation.ValueAnimator;
public class TestActivity extends ActionBarActivity {
private ImageView image;
private Button animateButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
image = (ImageView) findViewById(R.id.imageView);
animateButton = (Button) findViewById(R.id.button);
final ValueAnimator animator = ValueAnimator.ofInt(0, 100);
animator.setTarget(android);
animateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
animator.start();
}
});
}
}
When I click on the "Animate" button, no animation takes place and the image remains as it is. I just can't figure out how to get this is thing working. Any help regarding this issue will be highly appreciated.
Thanks in advance.
However, the official documentation for the ValueAnimator class does not contain enough details(at least, for beginners).
The key bit that you may have missed is:
[Using a plain ValueAnimator], however, has no real effect on an object, because the ValueAnimator does not operate on objects or properties directly.
Change your ValueAnimator to a property animator:
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "x", 0f, 100f);
and drop the setTarget() line.
Or, use the simpler syntax:
image.animate().x(100f);
I am using the following project: https://github.com/umano/AndroidSlidingUpPanel
It works very nicely so far, but I have one issue: I want to hide the slidable panel until I press a button, then the panel should be faded in, with an animation; currently the panel is shown when the button is pressed, but without an animation, and I don't know how to implement said animation.
Any ideas would be very much welcome!
I know it's been 4 months since you asked, but I decided to post an answer anyways (so someone else can maybe benefit from it).
Fading in the slideable panel is relatively easy. You just need to start an AlphaAnimation on layout that represents the slideable panel. You will probably need to disable the panel shadow by adding
sothree:shadowHeight="0dp"
to the major layout in your xml.
The more interesting thing is when you want to expand the slideable panel from the bottom of the screen (if panel is anchored at the bottom). In this case, you can use the following code:
import android.view.animation.Animation;
import android.view.animation.Transformation;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
public class SlidingUpPanelResizeAnimation extends Animation {
private SlidingUpPanelLayout mLayout;
private float mTo;
private float mFrom = 0;
public SlidingUpPanelResizeAnimation(SlidingUpPanelLayout layout, float to, int duration) {
mLayout = layout;
mTo = to;
setDuration(duration);
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float dimension = (mTo - mFrom) * interpolatedTime + mFrom;
mLayout.setPanelHeight((int) dimension);
mLayout.requestLayout();
}
}
And start the animation by:
SlidingUpPanelLayout slidingUpPanelLayout = (SlidingUpPanelLayout) findViewById(R.id.id_of_your_major_layout);
int slideablePanelHeight = 100;
int animationDuration = 800;
SlidingUpPanelResizeAnimation animation = new SlidingUpPanelResizeAnimation(slidingUpPanelLayout, slideablePanelHeight, animationDuration);
mSlidingLayout.startAnimation(animation);
I want to change the canvas image automatically.
Means i want that canvas image should be set one after another continuously.
I have written code which sets image only once.
But i don't know the code about changing the canvas image automatically so it creates the effect like Object is running on the road..
So what is the way to create such kind of animation in canvas ?
Please give me some ideas to create such 2D animation.
Thanx in Advance.
i would do this the following way:
create a custom view which contains a bitmap and in onDraw() this bitmap is drawn on the canvas
give this custom view a setter, to give it a new bitmap (maybe as a ressouce-id or something similar)
create a new Thread (with a UI-Handler) which changes the resource of the canvas at least 24times per second and calls customView.invalidate() via handler.post
this worked for me
edit: the code
Activity:
package de.test.animation;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
public class AnimationTestActivity extends Activity {
Button btn;
CustomView customView;
LinearLayout layout;
int[] imageIDs;
private void init(){ //array with my ressouce-IDs
imageIDs = new int[]{
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7,
R.drawable.pic8,
R.drawable.pic9,
R.drawable.pic10,
R.drawable.pic11,
R.drawable.pic12,
R.drawable.pic13,
R.drawable.pic14,
R.drawable.pic15,
R.drawable.pic16,
R.drawable.pic17,
R.drawable.pic18,
R.drawable.pic19,
R.drawable.pic20,
R.drawable.pic21,
R.drawable.pic22,
R.drawable.pic23,
R.drawable.pic24
};
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
btn = (Button) findViewById(R.id.btnStart);
layout = (LinearLayout)findViewById(R.id.layout);
customView = new CustomView(this);
customView.setNewImage(imageIDs[0]);
layout.addView(customView);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Thread t = new Thread(){
private final int FPS = 24; //How many frames will be dran per second
private final int SLEEPTIME = 1000/FPS; //Time, the thread waits, before drawing the next picture
#Override
public void run() {
super.run();
for(int i=0;i<imageIDs.length;i++){
customView.setNewImage(imageIDs[i]); //set next picture
customView.repaint(); //draw the picture on the canvas
try {
sleep(SLEEPTIME); //wait, until the next picture can be drawn
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
}
});
}
}
CustomView:
package de.test.animation;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;
public class CustomView extends View {
private Bitmap image; //image to be drawn on this view
private Context context;
public CustomView(Context context) { //constructor
super(context);
this.context = context;
}
public void setNewImage(int r_id){ //method to set a new picture (via resouce-id)
image = BitmapFactory.decodeResource(context.getResources(), r_id); //decode the image from the resouces
}
public void repaint(){ //method to repaint this view
this.post(new Runnable(){ //posting via a new runnable (otherwhise you get a "calledByWrongThreadException"
#Override
public void run() {
invalidate(); //Thread initiates UI-Thread to update this view
}
});
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(image, 0, 0, new Paint()); //draw the picture in the view
}
}
I hope this helps you.
Good luck then.
Check out this tutorial of frame animation:
http://www.youtube.com/watch?v=iTKtT-R98EE
More info can be found at following links:
Starting Frame-By-Frame Animation
Following is the step by step procedure:
In Frame Animation you will be swapping frames repeatedly, so that it appears continuous to the human eye and we feel that it is animated. Frame is referred to an image. So to implement frame animation one needs to have set of images, which describes a motion.
Step 1- Create a drawable folder.
Within it create an animation_list.xml file.
It includes :
A list of items that has the addresses of the frame images.
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="#drawable/blank" android:duration="210" />
<item android:drawable="#drawable/logo" android:duration="210" />
<item android:drawable="#drawable/logo1" android:duration="210" />
<item android:drawable="#drawable/logo2" android:duration="210" />
<item android:drawable="#drawable/logo3" android:duration="210" />
<item android:drawable="#drawable/logo4" android:duration="210" />
<item android:drawable="#drawable/logo5" android:duration="210" />
<item android:drawable="#drawable/logo6" android:duration="210" />
<item android:drawable="#drawable/logofinal" android:duration="210" />
</animation-list>
Step 2- Create an activity_main.xml file
It Includes : An Image View
<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" >
<ImageView
android:id="#+id/imageAnimation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />
</RelativeLayout>
Step 3- Outside the onCreate method :
Declare the Image View and Animation Drawable
// Declaring an Image View and an Animation Drawable
ImageView view;
AnimationDrawable frameAnimation;
Step4- Inside the OnCreate method:
Typecast the Image view
Typecast the Animation Drawable
Set the drawable backgroung on the image view
// Typecasting the Image View
view = (ImageView) findViewById(R.id.imageAnimation);
// Setting animation_list.xml as the background of the image view
view.setBackgroundResource(R.drawable.animation_list);
// Typecasting the Animation Drawable
frameAnimation = (AnimationDrawable) view.getBackground();
Step5- After the onCreate method :
The animation should only run when it is in focus that is when it is visible to the user. Hence define this method after the onCreate method.
// Called when Activity becomes visible or invisible to the user
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
// Starting the animation when in Focus
frameAnimation.start();
} else {
// Stoping the animation when not in Focus
frameAnimation.stop();
}
}
Source