In imageAdapter class, I set the image alpha to 0.5 handler.imageView.setAlpha(0.5f); inside a try/catch.
It's made like this, and not inside the layout xml, because previous versions of android haves int instead of float, so, in the catch, setAlpha is 128.
In the activity, I have an AlphaAnimation(float from, float to) so I can make smoother transitions when sliding between items. I've put from = 0.5f to match the initial value, and to = 1.0f to full opaque image. I really achieved a part from this. The item that is not selected shows an alpha with 0.5, but when it's selected, it's not 100% opaque, just a bit more.
Activity code:
private View antView = null; //Last view seen
...
gallery.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
if(antView != null)
setItemViewMode(antView, false);
antView = v;
setItemViewMode(v, true);
}
});
//This method is to detect the item selected, and change styles to selected and the view from before
public void setItemViewMode(View item, boolean selected) {
Animation animationImage;
ImageView img = (ImageView) item.findViewById(R.id.imageView1);
if(selected) {
animationImage = new AlphaAnimation(0.5f, 1.0f);
}
else {
animationImage = new AlphaAnimation(1.0f, 0.5f);
}
animationImage.setDuration(250);
animationImage.setFillAfter(true);
img.startAnimation(animationImage);
}
As said above, the animation occurs, but, the alpha from the selected image is not 100% opaque.
May something wrong setting the opacity inside the animation?
Find it out, someway, I thought that before adding the animation, I should put the opacity to 1.0f and then make the animation from 0.5f to 1.0f, and this worked.
So it would be:
if(selected)
animationImage = new AlphaAnimation(0.5f, 1.0f);
else
animationImage = new AlphaAnimation(1.0f, 0.5f);
img.setAlpha(1.0f);
img.startAnimation(animationImage);
try this...
public void setItemViewMode(View item, boolean selected) {
Animation animationImage;
ImageView img = (ImageView) item.findViewById(R.id.imageView1);
if(selected) {
animationImage = new AlphaAnimation(0f, 1.0f);
}
else {
animationImage = new AlphaAnimation(1.0f, 0f);
}
animationImage.setDuration(250);
animationImage.setFillAfter(true);
img.startAnimation(animationImage);
}
I have an activity where I am changing the ImageView periodically, for that I wrote the below line of code .
imageview.setImageUri(resId);
I am increasing the resource id .It works fine but there is sudden transition from one image to another. I don't want that,I want the smooth transition of image view to another image. How can i do that?
Try this
ImageView demoImage = (ImageView) findViewById(R.id.DemoImage);
int imagesToShow[] = { R.drawable.image1, R.drawable.image2,R.drawable.image3 };
animate(demoImage, imagesToShow, 0,false);
private void animate(final ImageView imageView, final int images[], final int imageIndex, final boolean forever) {
//imageView <-- The View which displays the images
//images[] <-- Holds R references to the images to display
//imageIndex <-- index of the first image to show in images[]
//forever <-- If equals true then after the last image it starts all over again with the first image resulting in an infinite loop. You have been warned.
int fadeInDuration = 500; // Configure time values here
int timeBetween = 3000;
int fadeOutDuration = 1000;
imageView.setVisibility(View.INVISIBLE); //Visible or invisible by default - this will apply when the animation ends
imageView.setImageResource(images[imageIndex]);
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator()); // add this
fadeIn.setDuration(fadeInDuration);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator()); // and this
fadeOut.setStartOffset(fadeInDuration + timeBetween);
fadeOut.setDuration(fadeOutDuration);
AnimationSet animation = new AnimationSet(false); // change to false
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
animation.setRepeatCount(1);
imageView.setAnimation(animation);
animation.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
if (images.length - 1 > imageIndex) {
animate(imageView, images, imageIndex + 1,forever); //Calls itself until it gets to the end of the array
}
else {
if (forever == true){
animate(imageView, images, 0,forever); //Calls itself to start the animation all over again in a loop if forever = true
}
}
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
}
Try alpha animation. First fadeout the imageview, on animation end, change the resource and then fadein the imageview.
For a smooth transition you must use Animations in Android, start by reading the following link:
http://www.vogella.com/articles/AndroidAnimation/article.html
There are many similar questions on stackoverflow about animations and many tutorials are available on the net about this topic. A simple search on google will bring you tons of result
I use animation in my app. My animation is moving a small layout to a point where its half way out of the screen, that way I want it.
My problem is that when I use params.setMargins(500, 0, 0, 0); resetButton.setLayoutParams(params);, the layout rearrange itself and all the views in it are become small and crushed.
I want the layout to stay the way it is despite it being out side of the screen. Is that Possible?
I'll add my code:
SetAnimationParameters(true);
mainLayout.startAnimation(animationSet);
animationSet.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
mainLayout.clearAnimation();
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mainLayout
.getLayoutParams();
params.setMargins(500, 0, 0, 0);
mainLayout.setLayoutParams(params);
}
});
and thats where I set the animation parameters:
private void SetAnimationParameters(boolean isRight) {
if (isRight) {
TAnimation = new TranslateAnimation(0, 500, 0, 0);
} else {
TAnimation = new TranslateAnimation(500, 0, 0, 0);
}
TAnimation.setDuration(250);
animationSet = new AnimationSet(false);
animationSet.setFillAfter(true);
animationSet.addAnimation(TAnimation);
}
As you can see after the animation is done (onAnimationEnd), I am translating the view to where the animation has ended, so it will be usable. But after that (and that is my problem) the layout is rearranged so all the views in it will not be out of the screen by shrinking them and I don't want that. I want the view to keep on being half way out.
Did I manage to be clear?
I have performed a Translation animation on button ,everything work as i excepted ,but only the problem is after the animation the button not responding to click event please correct me
Button b=(Button)findViewById(R.id.button1);
TranslateAnimation slide=new TranslateAnimation(0, 30, 0,-40);
slide.setDuration(500);
slide.setZAdjustment(TranslateAnimation.ZORDER_TOP);
slide.setFillAfter(true);
b.startAnimation(slide);
This will translate the object in y direction:
ObjectAnimator mover = ObjectAnimator.ofFloat(v, "translationY", 0, 400);
mover.start();
If you are handling animations at lower level API (below HoneyComb) your animation actually does not moves the button but only its images.Its click will be at same place where you have placed it in your layout.
I faced this issue and I did fix it just some second ago. So, I think that I should share my solution with you guys.
In animation xml file,I removed android:fillAfter="true" when keep android:fillEnabled="true".
Register Animation listener, then in onAnimationEnd() method, I call View#Layout() to change the position of the view.
int newLeft = (int) (layoutContent.getLeft() + layoutContent.getWidth() * 0.8);
layoutContent.layout(newLeft,
layoutContent.getTop(),
newLeft + layoutContent.getMeasuredWidth(),
layoutContent.getTop() + layoutContent.getMeasuredHeight());
In my case, what the animation do is that slides the layoutContent to leftside 80% of width.
It works fine. Hope this helps.
#Update: Today, you can use ObjectAnimator on android 3.0 +. If you are developing for android under 3.0, you can find it at support library v.4. ObjectAnimator is bester for animation.
#Update#2: You can use ViewPropertyAnimator on android api higher 12 version.
It provides better performance, and fix problem with click events. Example:
mButton.animate()
.setDuration(TIME)
.translationY(VALUE)
.start();
I could achieve what you wanted but you will have manage co-ordinates manually.
See if it works for you.
public class AnimationTestActivity extends Activity {
private Button mButton;
private LinearLayout.LayoutParams params;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mButton = (Button) findViewById(R.id.button);
mButton.setOnClickListener(mClickListener);
params = (LayoutParams) mButton.getLayoutParams();
}
private android.view.View.OnClickListener mClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 400);
animation.setDuration(2000);
animation.setAnimationListener(mAnimationListener);
v.startAnimation(animation);
}
};
private AnimationListener mAnimationListener = new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
params.topMargin = params.topMargin + 400;
mButton.setLayoutParams(params);
}
};
}
The animation do not change the View actually Position. even if you setfillAfter(true), The position it can accept click event is the original position.
I found an easy solution define the button final position in layout and start the animation from some position ,ie specify the fromX or fromY instead of putting as zero
Try to use this:
b.layout(0, -40, b.getWidth(), b.getHeight());
I'm using an xml defined animation to slide a view off the screen. The problem is, as soon as the animation completes it resets to its original position. I need to know how to fix this. Here's the xml:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="#android:anim/accelerate_interpolator">
<translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="500"/></set>
Here's the Java that I use to call it:
homeScrn = (View)findViewById(R.id.homescreen);
slideLeftOut = AnimationUtils.loadAnimation(this, R.anim.slide_left_out);
//Set Click Listeners For Menu
btnHelp.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
LayoutInflater.from(getApplicationContext()).inflate(R.layout.help, (ViewGroup)findViewById(R.id.subpage), true);
homeScrn.startAnimation(slideLeftOut);
}
});
So basically what happens is I inflate a view underneath one. Then I animate the view on top off to the left. As soon as it gets off screen and the animation is finished it resets its position back.
Finally got a way to work around,the right way to do this is setFillAfter(true),
if you want to define your animation in xml then you should do some thing like this
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/decelerate_interpolator"
android:fillAfter="true">
<translate
android:fromXDelta="0%"
android:toXDelta="-100%"
android:duration="1000"/>
</set>
you can see that i have defined filterAfter="true" in the set tag,if you try to define it in translate tag it won't work,might be a bug in the framework!!
and then in the Code
Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out);
someView.startAnimation(anim);
OR
TranslateAnimation animation = new TranslateAnimation(-90, 150, 0, 0);
animation.setFillAfter(true);
animation.setDuration(1800);
someView.startAnimation(animation);
then it will surely work!!
Now this is a bit tricky it seems like the view is actually move to the new position but actually the pixels of the view are moved,i.e your view is actually at its initial position but not visible,you can test it if have you some button or clickable view in your view(in my case in layout),to fix that you have to manually move your view/layout to the new position
public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
new TranslateAnimation(-90, 150, 0, 0);
now as we can see that our animation will starts from -90 x-axis to 150 x-axis
so what we do is set
someView.setAnimationListener(this);
and in
public void onAnimationEnd(Animation animation)
{
someView.layout(150, 0, someView.getWidth() + 150, someView.getHeight());
}
now let me explain public void layout (int left, int top, int right, int botton)
it moves your layout to new position first argument define the left,which we is 150,because translate animation has animated our view to 150 x-axis, top is 0 because we haven't animated y-axis,now in right we have done someView.getWidth() + 150 basically we get the width of our view and added 150 because we our left is now move to 150 x-axis to make the view width to its originall one, and bottom is equals to the height of our view.
I hope you people now understood the concept of translating, and still you have any questions you can ask right away in comment section,i feel pleasure to help :)
EDIT Don't use layout() method as it can be called by the framework when ever view is invalidated and your changes won't presist, use LayoutParams to set your layout parameters according to your requirement
The animations are working as expected. Just because you animated something does not mean you actually moved it. An animation only affects drawn pixels during the animation itself, not the configuration of the widgets.
You need to add an AnimationListener, and in the onAnimationEnd() method, do something that makes your move permanent (e.g., removes the view on top from its parent, marks the view on top as having visibility GONE).
I might be a bit late in replying, but I have the solution for this:
Just add android:fillAfter="true"
in your xml
You can use
fillAfter=true
fillEnabled=true
your View will'not reset to original position, but if you have some buttons or something else in your view , their position will not change.
You must use ObjectAnimator , it works from API 11 level . It changes View position automatic,
here is the example
ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mContent_container, "translationX", startX, endX);
objectAnimator.setDuration(1000);
objectAnimator.start();
Thanks JUL for his answer
If your app not found object animator, change the API level from Project -> properties -> Android , than import android.animation.ObjectAnimator;
Regards Hayk
You need to add this command:
final Animation animSlideLeft = new TranslateAnimation(0, -80, 0,-350, 0, 0, 0, 0);
animSlideLeft.setFillAfter(true);
I went to the same question and solved it with setting the marginLeft at OnAnimationEnd()..
MarginLayoutParams params = (MarginLayoutParams) this.getLayoutParams();
params.setMargins(this.getWidth()*position, 0,0,0);
this.setLayoutParams(params);
This problem has bothered for more than a week.
And Muhammad's answer pointed me a strightforward way to solve it.
I used sever layout to implement side menus with animation.
"view.layout will not be persistent. You should use LayoutParams, which will be persistent."
Here's my solution:
(Use what kind of LayoutParameter is depended on your own parent's layout):
#Override
public void onAnimationEnd(Animation animation) {
FrameLayout.LayoutParams layoutParams=new FrameLayout.LayoutParams(screenWidth, screenHeight);
layoutParams.setMargins((int) -(screenWidth * RATE), 0,
(int) (screenWidth - screenWidth * RATE), screenHeight);
for(View v:views) {
v.setLayoutParams(layoutParams);
//v.layout((int) -(screenWidth * RATE), 0, (int) (screenWidth - screenWidth * RATE), screenHeight);
v.clearAnimation();
}
}
fillAfter = true will do the job to transform view to new animation positon.
rotateAnimation.fillAfter = true;
If anybody interested to move arrow_up & arrow_down animations for a recycle view expands/collapse behavior.
Initial state: Collapse
call the method with a child visibility flag(View.VISIBLE/View.GONE).
Below is code belongs to animations.
fun setArrowImage(imageView: ImageView, childVisibility: Int) {
val angleRange = if (childVisibility == View.VISIBLE) Pair(0F, 180F) else
Pair(100f, 0F)
val rotateAnimation = RotateAnimation(
angleRange.first, angleRange.second,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f
)
rotateAnimation.duration = 300
rotateAnimation.fillAfter = true;
imageView.startAnimation(rotateAnimation)
}
Use helper methods below to easily animate your view. Then you can animate and reset after completion like this:
// Animate the view:
fly(
view1,
(float) 0,
(float) 0,
(float) 0,
(float) 1000,
250,
null,
null,
() -> {
// Return the view to initial position on animation end:
fly(
view1,
(float) 0,
(float) 0,
(float) 0,
(float) 0,
0);
return null;
});
Helper methods:
/**
* Translation of a view.
*/
public static void fly(
View view,
float fromXDelta,
float toXDelta,
float fromYDelta,
float toYDelta,
int duration) {
fly(
view,
fromXDelta,
toXDelta,
fromYDelta,
toYDelta,
duration,
null,
null,
null);
}
/**
* Translation of a view with handlers.
*
* #param view A view to animate.
* #param fromXDelta Amount to shift by X axis for start position.
* #param toXDelta Amount to shift by X axis for end position.
* #param fromYDelta Amount to shift by Y axis for start position.
* #param toYDelta Amount to shift by Y axis for end position.
* #param duration Animation duration.
* #param start On animation start. Otherwise NULL.
* #param repeat On animation repeat. Otherwise NULL.
* #param end On animation end. Otherwise NULL.
*/
public static void fly(
View view,
float fromXDelta,
float toXDelta,
float fromYDelta,
float toYDelta,
int duration,
Callable start,
Callable repeat,
Callable end) {
Animation animation;
animation =
new TranslateAnimation(
fromXDelta,
toXDelta,
fromYDelta,
toYDelta);
animation.setDuration(
duration);
animation.setInterpolator(
new DecelerateInterpolator());
animation.setFillAfter(true);
view.startAnimation(
animation);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
if (start != null) {
try {
start.call();
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onAnimationEnd(Animation animation) {
if (end != null) {
try {
end.call();
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onAnimationRepeat(
Animation animation) {
if (repeat != null) {
try {
repeat.call();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
Nothing from answers worked with me; although #Muhammad Babar answer inspired me to get a solution:
He mentioned that we can layout the view to the new position upon animation end:
public void onAnimationEnd(Animation animation) {
someView.layout(150, 0, someView.getWidth() + 150, someView.getHeight());
}
Although this didn't work with me instead; I had to do that in a Handler with delayed Runnable using a delay value that is slightly less than the animation duration.
So, in my case the animation duration is 500 msec, and I used a handler on 450 mesec, so it gets triggered just before the animation ends by 50 msec.
Handler().postDelayed({
someView.layout(150, 0, someView.width + 150, someView.hight)
someView.requestLayout()
someView.forceLayout()
}, 450)