Strange effect with ImageView startAnimation in ListView - android

after some months of coming here now and then it's finally my turn to submit my problem :
I have a ListView with a custom ArrayAdapter that loads images from the internet (one image per row). I made an ImageCache class that calls an onImageLoaded method on my ArrayAdapter :
public void onImageLoaded(Bitmap image, ImageView view){
view.setImageBitmap(image);
Utils.log("start animation : " + view.toString());
view.startAnimation(mAnim);
}
The problem is each time startAnimation (supposedly a fadeIn) is called on ONE ImageView, the animation seems to re-run from the start on ALL ImageView-s currently being animated, causing some weird blinking of several (or all) images when scrolling.
Utils.log say that startAnimation is called normally though (ie only once for each new ImageView appearing in the ListView).
The content of my animation XML is as such :
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:shareInterpolator="true">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0" android:duration="400"/>
</set>
Has this ever happened to anyone?
Can you see what i'm doing wrong?
Thanks!

The problem is cause by loading the Animation and storing it instead of creating a new Animation each time.
Solution example:
public void onImageLoaded(Bitmap image, ImageView view){
view.setImageBitmap(image);
Animation fadeInAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.fade_in);
view.startAnimation(fadeInAnimation);
}
Note the addiction of this line of code to the method above:Animation fadeInAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.fade_in);

Related

How to make setOnClickListener on a dynamic imageview

Working in Android Studio, I need to add in my app a click listener on my imageview which has a certain animation. This is the code I have in MainActivity:
myImage.startAnimation(myAnimation);
myImage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//DO SOMETHING
}
});
myAnimation comes from an XML in anim folder which does a translational animation:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:interpolator="#android:anim/accelerate_interpolator"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:fromYDelta="0%p"
android:toYDelta="40%p"
android:duration="1000"/>
</set>
This works fine, although this click listener is set on the space that has the image on the layout (activity_main.xml) and does not follow the animation inserted in the image. If I click on the space which belongs to the image in the layout, the click listener starts even if the image is not there due to the animation.
Is there a way in which the click listener is attach to the imageview in motion?
Thank you
This happens because the xml Translate animation you are using, does not really animate the View's property, it just moves the pixels on the screen and so it just looks like it has changed position, that is why the OnClickListener is still active on the View's original position, because Android thinks the View never really moved.
Simple solution use ObjectAnimator or even better ViewPropertyAnimator. Both will animate the View's property and so the OnClicklistener will also change it's position with it.

How to animate views within each ListView items?

If you have used the Google+ app on Android you must have noticed the comments on posts are animated to show comments one by one using a fadeIn and fadeOut animation on each ListView item.
I want to achieve this type of animation for certain views like TextView, etc within each of my ListView item.
I can achieve the fadeIn and fadeOut animation part but the problem is where do I put the animation code for it to work independently for each inflated ListView item.
Any help would be appreciated. Thanks in advance.
Please use a BaseAdapter and put the necessary animation codes in your getView() method.
Just inflate the views and start the animations when the views are inflated for the first time. (Hint - when convertView == null)
Use the ViewHolder pattern to hold each of the elements of the single list item uniquely and start animations no any View you need inside each list item.
To start animations, create an animation in XML and start the animation like this,
Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_up);
anim.setInterpolator(new DecelerateInterpolator());
anim.setDuration(500);
anim.setStartOffset(100);
anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
progress.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
progress.startAnimation(anim);
To give you an idea on how to create animations in XML,
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="200"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
<translate
android:duration="200"
android:fromYDelta="0%p"
android:toYDelta="5%p" />
</set>
You can use an animation set to combine multiple animations together and play them at once.
Please also explore the Animation API in greater detail, you will find useful methods like setRepeatMode() and setRepeatCount() which will help you to achieve the desired result.
Moreover, you do not need two separate TextViews, you can do it using one. Just make proper use of the animation listeners.
Hope it helps.

Best way to implement custom view with animation at the center of the screen?

My GOAL is to implement custom toast in my application as follows:
MyCustomToastClass.makeText(context,View,anyDurationInMS);
I want to set the "Toast" gravity, Layout, duration(not just Length.SHORT/LONG)
Things i've tried so far:
Class with windowManager object
problem was it must implement android system animation in:
params.windowAnimations
and when I tried to implement my custom animation as followed:
windowManager.addView(mLayout);
Animation AlphaAnimation = new ...
it didn't implement my animation.
Class with the rootView element to add the Toast's layout to it:
In this way I succeeded to implement everything only when the root view was FrameLayout type (With other layout I couldn't set the "Toast" gravity to center).
I would appreciate if someone has implemented this feature, Or to guide me if i'm missing something in one of my ways.
thanks
Sorry for misunderstand your question
if you want to create an pop up like toast and the duration is up to you maybe you can try to create a custom view that will contain the content you want to be toasted after that you can place your main layout in the frame layout then everytime the user trigger your custom toast you can add the custom view to your frame layout so it'll be positioned in front of your main layout and for fade in fade out animation you can use this
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator()); //add this
fadeIn.setDuration(1000);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator()); //and this
fadeOut.setStartOffset(1000);
fadeOut.setDuration(1000);
or if you want to use XML
FadeIn
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0.0"
android:toAlpha= 1.0"
android:duration="1000"
android:repeatCount="infinite"
android:repeatMode="reverse"
/>
FadeOut
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="1000"
android:repeatCount="infinite"
android:repeatMode="reverse"
/>
and for the time you can use
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// FADE OUT THE POP UP/TOAST HERE
}
}, /*SET THE TIME HERE*/);
I hope this answer is clear enough for you
and if you still have some question about my answer don't hesitate to ask in the comment :)

Android animation for dynamically loaded image

I want to create an animation for an image that is loaded into a vertical linear layout dynamically. When triggered I would like the image to slide down with its alpha set to 0 (this will slide all content below it down I hope) then fade the image in. Being new to Android animations I am having some trouble. Right now I'm trying to get just the fade in to work, here is what I have:
fade_in.xml
<?xml version="1.0" encoding="utf-8"?>
<alpha
xmlns:android="https://chemas.android.com/ap/res/android"
android:interpolator="#android:anim/anticipate_interpolator"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="5000" >
</alpha>
In the Activity:
Animation animation = AnimationUtils.loadAnimation(context, R.anim.fade_in);
ImageView image = new ImageView(context);
image.setImageResource(R.drawable.my_image);
image.setLayoutParams(layoutParams);
image.setAlpha(0);
((ViewGroup) view).addView(image, 0);
image.startAnimation(animation);
The image is being loaded as all the context below it is shifted down, however if never fades in. I would like to get this working as well as having the image slide down so the dynamica add does not look so choppy.
Thanks in advance.
You have a typo in the xmlns:android tag.
It should be
xmlns:android = "http://schemas.android.com/apk/res/android"
With that being corrected, just remove the image.setAlpha(0); and it should animate. I am afraid I cannot give you a reason why it doesn't work with the alpha attribute set to 0.
Regarding the slide down animation, you will have to subclass Animation. Have a look at this answer that I think can help you get what you want: https://stackoverflow.com/a/5122460/871102

How to stop an image which moves by animation?

I'm trying to move an image from left to right on layout, but not by dragging. I want it to go automatically when something happened. So, i found an animation like this:
<?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:duration="1000"
android:fromXDelta="0"
android:toXDelta="200"
android:fillEnabled="true"
android:fillAfter="true" />
</set>
But the problem is i couldn't find how to make it stop there! It's just went back directly. Any suggestion please?
Here is my Java code:
public void onClick(View v) {
runOnRight(this, image);
}
static Animation runOnRight(Activity ctx, View target) {
Animation animation = AnimationUtils.loadAnimation(ctx,
R.anim.slide_left_to_right);
target.startAnimation(animation);
return animation;
}
set FillAfter to true in your animation set xml
When the View.onAnimationEnd() callback is fired, you can set the new View postion with View.layout(int, int, int, int). The View.layout call assign size and position to your view. Refer to the documentation for more information
use the field FillAfter="true" which will stops at the end.
just like following.

Categories

Resources