Good day,
I'm trying to implement an Animation that slides in a WebView from below onto my screen.
Here's the code of my animation xml file:
slide_in_from_bottom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<translate android:fromYDelta="100%" android:toYDelta="0%"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="700"/>
</set>
Here is where I ask my WebView to slide in:
Animation slideIn = AnimationUtils.loadAnimation(this, R.anim.slide_in_from_bottom);
slideIn.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.d("animation", "started");
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
webView.setVisibility(View.VISIBLE);
Log.d("animation", "stopped");
}
});
webView.startAnimation(slideIn);
This works fine, but the problem is that my WebView does not always have the same size. This causes it to slide in really fast if it's a large WebView, and (relatively) slow if it's rather small.
I've tried using an ObjectAnimator as well:
ObjectAnimator moveInFromBottom = ObjectAnimator.ofFloat(webView,
"translationY", 900f, 0f);
moveInFromBottom.setDuration(700);
moveInFromBottom.start();
This works fine, but there is a bug that removes the cursor from an inputText in my WebView. (Really weird, can't find any info on it). Then I can still type in text in the inputText, but I can't remove it using backspace :S
So, my question is: How can I make sure my Animation always slides in at the same speed, whatever the height of my WebView is?
Related
I am working on a App that is simple in work and it is working quite efficiently. But I have one place where I am looking something is not looking great and that is flipping Animation.
What I Want :
I have a Button and a ImageView beneath the button. On a Button click I want to make a Animation that it looks like ImageView has flipped and next image is shown in the ImageView. So on every click it should show next image with a flipping animation but there are some problems. I would discuss later but first let me show you how I am doing this.
What I have done so far :
flipping.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0" android:valueTo="180" android:propertyName="rotationY" >
</objectAnimator>
in Activity
#Override
public void onClick(View v) {
flipAnimation();
ivAnimPicture.setImageResource(myImage1);
}
private void flipAnimation(){
ObjectAnimator anim = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.flipping);
anim.setTarget(ivAnimPicture);
anim.setDuration(1500);
anim.start();
}
Problem
When It rotates to 180 from 0 , when it comes exactly at 90 degree we can see image view edges so it makes the animation look not so good. and Also the image changes first then the Flipping animation starts where as I want that Flipping animation should start and in the middle of it the new image should appear. so when the animation stops there should be surprisingly new image for the user.
So I really do not want Image to set in the image-view and then the Animation starts and Animate the image view
Please suggest me more good way or if there is library which is not obsolete.
Chathuranga's solution will do the job. but you better:
1.Use ViewPropertyAnimator. Specially, when you need to perform different animations on several ImageViews.
2.rotate from 270f to 360f for second flip, otherwise your image will be mirrored.
3.Load your second Image into a Drawable before starting the animation, to have a smooth rotation.
final Drawable drawable=getResources().getDrawable(R.drawable.a);
final ImageView iv = ((ImageView)findViewById(R.id.imageView1));
iv.setRotationY(0f);
iv.animate().rotationY(90f).setListener(new AnimatorListenerAdapter()
{
#Override
public void onAnimationEnd(Animator animation)
{
iv.setImageDrawable(drawable);
iv.setRotationY(270f);
iv.animate().rotationY(360f).setListener(null);
}
});
I was in your situation trying to figure out how to get this animation done. Here's how I achieve this.
you need to define two animations. one to rotate from 0 degree to 90 degree and other for to rote from 90 degree to 180 degree
flipstage1.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="rotationY"
android:valueFrom="0"
android:valueTo="90">
</objectAnimator>
flipstage2.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="rotationY"
android:valueFrom="90"
android:valueTo="180">
</objectAnimator>
Place these two files under res/animator
In your code start first animation first, add a listener to it. On animation end change the image and start second animation.
ObjectAnimator animStage1 = (ObjectAnimator) AnimatorInflater.loadAnimator(getActivity(), R.animator.flipstage1);
final ObjectAnimator animStage2 = (ObjectAnimator) AnimatorInflater.loadAnimator(getActivity(), R.animator.flipstage2);
animStage1.setTarget(imageIcon1);
animStage2.setTarget(imageIcon1);
animStage1.setDuration(500);
animStage2.setDuration(500);
animStage1.start();
animStage1.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
animStage2.start();
imageIcon1.setImageDrawable(ResourcesCompat.getDrawable(view.getResources(),R.drawable.okicon,null));
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
imageIcon1 is the reference to image view in xml layout.
Try this simple piece of code and let me know
ObjectAnimator anim = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.flipping);
anim.setTarget(ivAnimPicture);
anim.setDuration(1500);
anim.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
ivAnimPicture.setImageResource(myImage1);
}
});
anim.start();
I am simply translating a cardview that contains an image and textview, horizontally from outside the screen, to inside.
here is my animation xml which is referenced using android:layoutAnimation of the cardview xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-300"
android:toXDelta="0"
android:fromYDelta="0"
android:toYDelta="0"
android:duration="1000"/>
</set>
I want the card to maintain its look and animate as a whole from one point to another, but instead I get a weird delay between the card and its contained views making for an ugly animation, the below image is my best attempt to describe it visually:
Any help would be greatly appreciated!
I have done like this
ObjectAnimator settleAnimator;
if(settleAnimator==null){
settleAnimator = ObjectAnimator.ofFloat(yourView, "translationX", 0);
settleAnimator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
inAnimation = true;//just a boolean
}
#Override
public void onAnimationEnd(Animator animation) {
inAnimation = false;
}
#Override
public void onAnimationCancel(Animator animation) {
inAnimation = false;
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
}
settleAnimator.setDuration(200);//millisec
//this will take start value and end value in pixels ie. (from, to)
settleAnimator.setFloatValues(+300, 0);
settleAnimator.start();
}
The problem was that while I was testing different ways of doing this I left both the programmatic code and the xml code in, thus causing strange doubled up animations.
I want to implement sliding panel that slide on touch from top to bottom in Android like this design
You can also implement same via Translate Animation.
First you need to write xml file under res/anim folder.
slide_down_service.xml
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="#android:integer/config_longAnimTime"
android:fromXDelta="0%p"
android:toXDelta="0%p"
android:fromYDelta="0%"
android:toYDelta="120%">
</translate>
you can change YDelta value as per requirement.
Then you need to intialize Animations in following way in your activity.
Animation animContentDown = AnimationUtils.loadAnimation(
getApplicationContext(), R.anim.slide_down_service);
animContentDown.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
});
And then start your animation : yourview.startAnimation(animContentDown);
That's a sliding drawer. Implementation is easy, you just need the two views for the handle and the content. Be careful though, it has been deprecated.
Ok.. I got this animation set up for a small imageview for translating from "0%" to "50%" in XML...
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<translate
android:duration="400"
android:fromXDelta="0%"
android:toXDelta="+50%" />
</set>
After this, I need to add another sequential animation which would change the Y co-ordinate from "0%" to "50%".. I tried adding another <set> but it did not work... What should I do to get sequential animation?
You can use android:startOffset to delay animations. Delay in milliseconds before the animation runs, once start time is reached. Must be an integer value, such as "100". -- "developer.android.com"
Another way is you can use AnimationListener to "listen" animations and do whatever you want.
This link is useful for you: How to run several translate animations sequentially?
I'm not completly sure what you really want to do, but if you want to "translate" both the "x" and "y" at the same time simply add android:fromYDelta="0%" and android:toYDelta="+50%" to your existing <translate>.
If you want to "translate" the Y values after the X ones, you will need a new XML file, which you will need to call when the X ones finish.
A quick, untested example:
mAnimatedView = findViewById(R.id.viewToAnimate);
mAnimX = (TranslateAnimation) AnimationUtils.loadAnimation(mContext, R.anim.aX);
mAnimY = (TranslateAnimation) AnimationUtils.loadAnimation(mContext, R.anim.aY);
mAnimX.setAnimationListener(new AnimationListener(){
#Override
public void onAnimationEnd(Animation animation) {
if (mAnimatedView) {
mAnimatedView.startAnimation(mAnimY);
}
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
});
mAnimY.setAnimationListener(new AnimationListener(){
#Override
public void onAnimationEnd(Animation animation) {
if (mAnimatedView) {
mAnimatedView.startAnimation(mAnimX);
}
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
});
mAnimatedView.startAnimation(mAnimX);
Hope that helps and is clear enough.
I have a ListView on screen and a menu at the bottom. Upon a click of menu key, it animates-slides off the screen and the ListView expands.
menuBtmVisable = false;
Animation menu_off = AnimationUtils.loadAnimation(this, R.anim.menu_off);
menubtm.startAnimation(menu_off);
Display display = getWindowManager().getDefaultDisplay();
LayoutParams listlp = new LayoutParams(display.getWidth(), display.getHeight()-87 , 0, 50);
ListViewMain.setLayoutParams(listlp);
menu_off.xml
<set
android:fillEnabled="true"
android:fillAfter="true"
xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0"
android:toYDelta="120"
android:duration="500"
/>
</set>
Yet when, with the menu down, I click on the ListView item "13" ( see picture ), it results in a menu click, as if it is still in place...
What do you think would be the best way to take care of it?
I've looking for an answer for a problem like that, and finally, after a week, I've managed to solve my problem. Since it looks similar to yours, maybe it will help you.
Set up and AnimationListener() in your animation and, onAnimationEnd, change the layout as you want. In my case, I wanted to slide a layout up, so 2 buttons would appear from below. However, the layout just slided visually; the buttons would still be off screen, interactionally speaking. So I have something like this:
final View screen = findViewById(R.id.welcome_screen);
final Animation a = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_home_up);
a.setFillAfter(true);
a.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
screen.clearAnimation();
screen.setPadding(0, -222, 0, 0);
}
});
screen.startAnimation(a);