How can I animate a custom view (ImageView) programmatically? - android

I want to animate a custom view programmatically. I want it to only animate in the position where it is declare in the xml file, and I don't want it to mess the layout. Also this animation is affected by other factor so the android Animation class is out of the question.
I have test this sample tutorial and watch this videos. My problem is that most tutorial is for animating a sprite into a canvas where you will trace your sprite's location.
How can you animate the custom view without affecting layout and without using the Android Animation class?
Edited:
The custom view will act as a animated-gif and will toggle another set of frames whenever an event activates it.

you can create animation XML and apply that animation from program to your ImageView check following example
you can start animation for your customized view just call viewobject.startAnimation(animationobject);
animation.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="700" />
<set
android:interpolator="#android:anim/accelerate_interpolator"
android:startOffset="700">
<scale
android:fromXScale="1.4"
android:toXScale="0.0"
android:fromYScale="0.6"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="400" />
<rotate
android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="400" />
</set>
your main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
/>
<ImageView android:id="#+id/ImageView01" android:layout_width="wrap_content" android:layout_height="wrap_content"></ImageView>
</LinearLayout>
then your activity class myActivity.java
public class myActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView image = (ImageView) findViewById(R.id.ImageView01);
//create animation class object
Animation hyperspaceJump =
AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
//start animation for image
image.startAnimation(hyperspaceJump);
}
}

If you want "frame by frame" animation that just "runs" like an animated gif, you can follow:
drawable-animation official tutorial.
Quoting from the tutorial:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="#drawable/rocket_thrust1" android:duration="200" />
<item android:drawable="#drawable/rocket_thrust2" android:duration="200" />
<item android:drawable="#drawable/rocket_thrust3" android:duration="200" />
</animation-list>
and in your code
AnimationDrawable rocketAnimation;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
rocketAnimation.start();
return true;
}
return super.onTouchEvent(event);
}

Related

Android specific animations Xamarin.Forms - Splash screen

I have made a splash screen for Android by implementing a new Activity. It points to a xml theme that includes android specific code (#style/Splash). That points to a drawable xml of splash.
My question is, If we can do these kinds of platform specific implementations, can we also create animations using this same pattern? I have placed an example of code from the android dev website to give you an idea of what I am trying to include. If yes, what would this code look like in XF.Android and how can we reference it?
SplashActivity.cs
[Activity(Label = "SplashActivity", Theme = "#style/Splash", MainLauncher = true, NoHistory = true)]
public class SplashActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
StartActivity(typeof(MainActivity));
}
}
style/Splash
<style name="Splash" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">#drawable/splash</item>
</style>
drawable/splash
<?xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<color android:color="#03045E"/>
</item>
<item>
<bitmap
android:src="#drawable/logo1"
android:tileMode="disabled"
android:gravity="center"/>
</item>
</layer-list>
Example anim that I want to include hyperspace_jump.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="700" />
<set
android:interpolator="#android:anim/accelerate_interpolator"
android:startOffset="700">
<scale
android:fromXScale="1.4"
android:toXScale="0.0"
android:fromYScale="0.6"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="400" />
<rotate
android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="400" />
</set>
</set>
1. Create a Anim folder and put the hyperspace_jump.xml file in it.
2. Create the layouts.
SplashScreen Layout:
<RelativeLayout xmlns:p1="http://schemas.android.com/apk/res/android"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="match_parent"
p1:layout_height="match_parent"
p1:background="#android:color/white"
p1:id="#+id/relativeLayout1">
<ImageView
p1:layout_width="wrap_content"
p1:layout_height="wrap_content"
p1:id="#+id/imageView"
p1:layout_centerVertical="true"
p1:layout_centerHorizontal="true"
p1:src="#drawable/a01" />
</RelativeLayout>
Main Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<TextView
android:text="Main Activity Started"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView1"/>
</LinearLayout>
3. Code Behind:
SplashScreenActivity:
public class SplashScreenActivity : Activity
{
ImageView imageView;
Animation view_animation;
TextView textview;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
RequestWindowFeature(Android.Views.WindowFeatures.NoTitle);
SetContentView (Resource.Layout.SplashScreen);
imageView = (ImageView)FindViewById(Resource.Id.imageView);
view_animation = AnimationUtils.LoadAnimation(this,Resource.Animation.hyperspace_jump);
imageView.StartAnimation(view_animation);
view_animation.AnimationEnd += Rotate_AnimationEnd;
}
private void Rotate_AnimationEnd(object sender, Animation.AnimationEndEventArgs e)
{
Finish();
StartActivity(typeof(MainActivity));
}
}
MainActivity:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
Toast.MakeText(this, "Welcome to MainActivity", ToastLength.Long).Show();
}
4. Screenshot:
You could download from the GitHub for reference. https://github.com/WendyZang/Test/tree/master/SplashScreenDemo

Why image rotation animation only works correctly for the first time

I have this simple arrow image rotation animation which works as intended only for the first time. from second time onward It's still do the rotation but without slow animation.
Here's the code in anim xml files
Rotate 180
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1500"
android:fromDegrees="0"
android:toDegrees="180"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:fillAfter="true"
android:fillEnabled="true"/>
Rotate Revere
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1500"
android:fromDegrees="180"
android:toDegrees="0"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:fillAfter="true"
android:fillEnabled="true"
/>
The image view inside card view.
<ImageView
android:id="#+id/creadit_card_next_image"
android:layout_width="#dimen/next_image_size"
android:layout_height="#dimen/next_image_size"
android:layout_marginEnd="#dimen/static_menu_primary_margin"
android:layout_marginTop="16dp"
android:rotation="-90"
android:src="#drawable/ic_navigate_next"
android:tint="#color/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Java code to trigger Animation.
private Animation rotatePlus180;
private Animation rotateMinus180;
private boolean creditDebitCardViewExpanded = true;
rotatePlus180 = AnimationUtils.loadAnimation(this, R.anim.rotate_plus_180);
rotateMinus180 = AnimationUtils.loadAnimation(this, R.anim.rotate_minus_180);
private void onClickCreditDebitCardView() {
creditDebitCardPaymentMethod.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (creditDebitCardViewExpanded) {
expandAnimation(paymentRecyclerView);
creditDebitCardViewExpanded = false;
creditCardNextImage.setAnimation(rotatePlus180);
} else {
collapseAnimation(paymentRecyclerView);
creditDebitCardViewExpanded = true;
creditCardNextImage.setAnimation(rotateMinus180);
CreditDebitLayoutContainer.setPadding(0, 0, 0, padding);
}
}
});
}
Instead of setAnimation use startAnimation
creditCardNextImage.startAnimation(rotatePlus180);
creditCardNextImage.startAnimation(rotateMinus180);
setAnimation seems to be called once you attach the animation to the view/ or when the view is added.
StartAnimation will be called all the time even if the view has already been added.

Button animation: text is animated, but background shape is static

I have a button animation which is defined to scale from 1.0 to 1.1 and back. The text of the button ("Next") scales up and then down, but the button size does not change.
1. Is this expected behavior?
2. There is a jerk when it restarts the animation. I assume this is happening at the loadAnimation() call. Is there a way to make that seamless?
public void startAnimation() {
final View nextButtonView = fragmentActivity.findViewById(R.id.game2NextButton);
nextButtonView.setVisibility(View.VISIBLE);
Animation anim = AnimationUtils.loadAnimation(fragmentActivity, R.anim.scale_button);
anim.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation arg0) {
Animation anim = AnimationUtils.loadAnimation(fragmentActivity, R.anim.scale_button);
anim.setAnimationListener(this);
nextButtonView.startAnimation(anim);
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
});
nextButtonView.startAnimation(anim);
}
scale_button.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<scale
android:duration="1000"
android:fillBefore="false"
android:fillAfter="false"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.1"
android:toYScale="1.1" />
<set android:interpolator="#android:anim/decelerate_interpolator" >
<scale
android:duration="1000"
android:fillBefore="false"
android:fillAfter="false"
android:fromXScale="1.1"
android:fromYScale="1.1"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="1000"
android:toXScale="1.0"
android:toYScale="1.0" />
</set>
</set>
Next Button is in layout like so:
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal" >
<Button
android:id="#+id/game2NextButton"
style="#style/navigation_button"
android:contentDescription="#string/nextbutton"
android:text="#string/next" />
</LinearLayout>
Navigation button style:
<style name="navigation_button">
<item name="android:layout_width">320dp</item>
<item name="android:layout_height">80dp</item>
<item name="android:textColor">#drawable/text_color</item>
<item name="android:background">#drawable/navigation_button_shape</item>
<item name="android:onClick">onButtonClicked</item>
<item name="android:textSize">32sp</item>
<item name="android:textStyle">bold</item>
<item name="android:maxLines">1</item>
</style>
Button shape:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#color/darkgrey2" />
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
</shape>
Edit:
As Ercan suggests, then best approach is to use android:repeatMode="reverse" as below. Thus the animation is implemented entirely on xml.
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fillAfter="true"
android:fillBefore="true"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="#android:anim/decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:toXScale="1.1"
android:toYScale="1.1" />
This is an expected behavior. The view animation does not really scale the view bounds. It only scales the image of it. Use ObjectAnimator for this purpose. if you are supporting pre honeycomb i recommd Jake Wharton's 9olddroids library
2.As I see from here, you are trying to repeat the same animation infinitely by restarting.
you may do it by adding :
android:repeatCount="infinite"
and also you can use this to obtain more seamless result :
android:repeatMode="reverse"
I hope this helps.

How to get the animated view

here is xml fileļ¼š
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="150dp"
android:layout_height="match_parent">
<Button
android:id="#+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
here is java code
private Button text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (Button)findViewById(R.id.textview);
text.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
text.startAnimation(getScaleAnimation());
}
});
}
private ScaleAnimation getScaleAnimation(){
ScaleAnimation animation = new ScaleAnimation(1f,1.2f,1f,1.2f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animation.setDuration(1000);
animation.setFillAfter(true);
return animation;
}
I am performing a simple ScaleAnimation on a Button.Is there any way I can get the animated view?
Just open anim folder inside res folder. Create an xml file. Then you need to create set tag. Inside of it, you can create scale tag.
Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator">
<scale
android:fromXScale="0.5"
android:toXScale="2"
android:fromYScale="0.5"
android:toYScale="2"
android:pivotX="50%"
android:pivotY="50%"
android:duration="5000"
/>
</set>
Note: do not forget to include xmlns:android declaration.
Now, inside of onCreate method or wherever you want, just put following. I am animating(scaling) a button itself when it is clicked:
Button but = (Button) findViewById(R.id.button1);
but.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Animation anim = AnimationUtils.loadAnimation(AnimationActivity.this, R.anim.animation);
but.startAnimation(anim);
}
});
EDIT:
in case you want to rotate it while scaling, you can put following inside of the xml file:
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="5000"
/>
Hope this helps.
Use this way
Create an xml inside /res/anim folder and put the below code into it.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<scale android:fromXScale="0.0" android:fromYScale="0.0"
android:toXScale="1.0" android:toYScale="1.0"
android:duration="700" android:fillBefore="false" />
</set>
Place the below code inside the java file:
Animation scaleAnimation
= AnimationUtils.loadAnimation(this, R.anim.logoanimation);
Btn.startAnimation(scaleAnimation);
logoanimation is the name of my animation xml file.
for more refer this tutorial

Rotate animation android

I'm trying to do a rotating image animation.
I need to rotate an icon around itself just like they do in a progressbar, but what I'm getting is an image rotating around a circle.
Here is my animation code
<?xml version="1.0" encoding="utf-8"?>
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2500"
android:repeatCount="infinite"
android:repeatMode="restart"
/>
Where am I going wrong in here?
Thanks
This is the source code for the layout main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/testButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="animationText"
android:onClick="AnimClick"/>
<ImageView
android:id="#+id/testImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:contentDescription="image_desc"
android:scaleType="fitCenter"
android:src="#drawable/cat2" />
</RelativeLayout>
To implement the rotation animation, we can define the animation by XML or Java code. If we want to write the animation in the xml, we need to create an animation xml file under /res/anim folder. Here, we create a xml file named rotate_around_center_point.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<rotate
android:duration="2500"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toDegrees="360" />
</set>
and this is my Activity:
public class MainActivity extends Activity implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.testButton);
btn.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
ImageView animationTarget = (ImageView) this.findViewById(R.id.testImage);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate_around_center_point);
animationTarget.startAnimation(animation);
}
}
You could try with the following code, rather than doing it in XML:
RotateAnimation rotate = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
rotate.setDuration(4000);
rotate.setRepeatCount(Animation.INFINITE);
yourView.setAnimation(rotate);
Well I got where I was wrong. I gave padding to my image which caused it to move aside a little every time it rotated.
Anyhow I removed the padding and now it's working just fine.
Add the following xml in the animation folder
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false"
android:duration="4000"
android:fromdegrees="0"
android:pivotx="50%"
android:pivoty="50%"
android:todegrees="360"
android:toyscale="0.0">
</set>
Hope this will help you..
for more information http://www.blazin.in/2013/09/simple-rotate-animation-in-android.html

Categories

Resources