How to rotate ImageButton source Image with Animation. - android

I need to rotate the drawable resource of ImageButton. I've succeeded rotating functionality to my Button but rotating functionality affect whole button. All I want to do is rotate only drawable inside ImageButton.
How to handle this situation ?
PS: I accessed drawable inside ImageButton but I wasn't able give any animation functionality.
Thanks in helpings
Here my ImageButton xml;
<ImageButton
android:id="#+id/button"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical"
android:layout_marginTop="-40dp"
android:background="#color/titlebackground_color"
android:src="#drawable/open" />
Rotate first xml;
<?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:fromDegrees="-180"
android:toDegrees="-360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="500"
android:startOffset="0"
/>
</set>
Rotate Second xml;
<?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:fromDegrees="-180"
android:toDegrees="-0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="500"
android:startOffset="0"
/>
</set>
Animation functionality;
public class LayerInfoFragment extends Fragment {
int count = 0;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.layer_info_main, container, false);
btnClose = (ImageButton) v.findViewById(R.id.button);
btnClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Animation rotate = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_first);
Animation rotatex = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_last);
if (count % 2 == 0) {
v.setRotation(180);
v.setAnimation(rotate);
} else {
v.setRotation(0);
v.setAnimation(rotatex);
}
count++;
}
});
}
}

There are 2 things to try I think.
1) Add code v.startAnimation(rotate); after v.setAnimation(). I suspect your animation never got started. I was thinking before that android:startOffset in the settings would trigger a start but that is not clear to me.
2) Try RotateAnimation, a direct subclass of Animation, instead of Animation objects. It seems many used RotateAnimation more than anything else. Besides that, the other issue I suspect is in the layout file.
Example:
RotateAnimation rotate = (RotateAnimation) AnimationUtils.loadAnimation...
Tell us what happens.

Related

Infinite loop of sequential animation of ImageButton

I'm new to android studio and I want to animate an imageButton with a sequential animation set. The animation set (animation_boutons.xml)is in res/anim.
I've tried with animationSet in java but the app crashed every time I launched the emulator.
I've spent a long time looking for a solution. I hope someone can help me !
I apologize if it's something obvious.
java code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
configureCodeurBouton();
}
private void configureCodeurBouton() {
ImageButton boutonCodeur = findViewById(R.id.boutoncodeur);
Animation animBoutons = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_boutons);
animBoutons.setRepeatCount(Animation.INFINITE);
boutonCodeur.setAnimation(animBoutons);
boutonCodeur.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, codeur.class));
}
});
}
}
xml code:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true"
android:fillAfter="true">
<rotate
android:fromDegrees="0"
android:toDegrees="20"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="0"
android:duration="1000"
/>
<rotate
android:startOffset="1000"
android:fromDegrees="20"
android:toDegrees="-20"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"
/>
<rotate
android:fromDegrees="-20"
android:toDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="3000"
android:duration="1000"
/>
</set>
Also, Vedprakash Wagh give me the advice to try animBoutons.setRepeatCount(Animation.INFINITE) but it has no effect).
Your app is crashing every time because you're trying to find your ImageButton when the class is created first, and not after the layout is set.
You're getting NullPointerException, as there is no ImageButton with id R.id.boutoncodeur in your View hierarchy when you're trying to find it.
You need to find your ImageView AFTER it is available in your View hierarchy i.e. after your setContentView();
You can either do this:
Remove your second line
ImageButton boutonCodeur = findViewById(R.id.boutoncodeur);
as you've already found your ImageView in your configureCodeurButton() function.
Or, you can keep one class variable of ImageView, and make findViewById call after setContentView like below.
public class MainActivity extends AppCompatActivity {
ImageButton boutonCodeur;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
boutonCodeur = findViewById(R.id.boutoncodeur);
configureCodeurBouton();
}
private void configureCodeurBouton() {
Animation animBoutons = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_boutons);
boutonCodeur.setAnimation(animBoutons);
boutonCodeur.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, codeur.class));
}
});
}
}
You can learn more about NullPointerException here. Also, learn how to read the errors from tutorials that are available. Or, simply open the logcat tab in Android Studio when the error occurs to know what Error you're getting.
To make your animation run infinitely, you can add this in your code.
animation.setRepeatCount(Animation.INFINITE)
I just had to change the whole xml anim_boutons file so I have only one animation and not three rotate animations. the repeatMode line says to repeat the animation backwards at each repeat. This gives the expected effect.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true"
android:fillAfter="true">
<rotate
android:fromDegrees="-20"
android:toDegrees="20"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="0"
android:duration="1000"
android:repeatCount="infinite"
android:repeatMode="reverse"
/>
</set>

Rotating an animation does not work after changing X,Y of an Image

I need to locate a click on one ImageView (image1) and then to set my second ImageView (image2) to the same position, and start a rotate animation on image2.
My animatiom works fine when i don't change image2 position.
When I want to change the position and start the animation together image2 is moving all over the screen.
My XML code:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:fromDegrees="0"
android:toDegrees="-50"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
/>
</set>
My java code is:
image1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
image2.setX(image1.getX());
image2.setY(image1.getY());
Animation animation =
AnimationUtils.loadAnimation(MainActivity.this, R.anim.myanim);
image2.startAnimation(animation);
}
});

Rotating an image continously

I have the following code that attempts to rotate an image continuously:
Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_animation);
image.startAnimation(animation);
The rotate_animation.xml file is as follows:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromDegrees="0"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="360" />
The problem with the above code is that it rotates the image and pauses before rotating it again. What I am looking for is smooth continuous rotation that that will only stop when I explicitly need it to stop.
Move over to property animators which is now the recommended approach for animations. Try this -
ImageView imageview = (ImageView)findViewById(R.id.yourimage);
ObjectAnimator imageViewObjectAnimator = ObjectAnimator.ofFloat(imageview ,
"rotation", 0f, 360f);
imageViewObjectAnimator.setRepeatCount(ObjectAnimator.INFINITE);
imageViewObjectAnimator.setRepeatMode(ObjectAnimator.RESTART);
imageViewObjectAnimator.setInterpolator(new AccelerateInterpolator());
imageViewObjectAnimator.start();
I have successfully used animated-rotate in an activity, see my rotate.xml
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="#drawable/ic_rounded_loading"
android:duration="1000"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite" />
and in activity_main.xml file,
<ImageView
android:id="#+id/ivLoading"
android:layout_width="200px"
android:layout_height="200px"
android:layout_centerHorizontal="true"
android:src="#drawable/rotate"
android:layout_centerVertical="true" />
But its not working on a fragment. So I figured it in a fragment by below code that rotates an image continously,
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Accessing the layout components to be displayed.
rootView = inflater.inflate(R.layout.fragment_loading, container, false);
ivLoading= (ImageView) rootView.findViewById(R.id.ivLoading);
RotateAnimation rotateAnimation = new RotateAnimation(
0,//float: Rotation offset to apply at the start of the animation.
360,//float: Rotation offset to apply at the end of the animation.
Animation.RELATIVE_TO_SELF,//int: Specifies how pivotXValue should be interpreted
0.5f,//float: The X coordinate of the point about which the object is being rotated
Animation.RELATIVE_TO_SELF,//int: Specifies how pivotYValue should be interpreted
0.5f//float: The Y coordinate of the point about which the object is being rotated
);
rotateAnimation.setDuration(1500);//How long this animation should last.
rotateAnimation.setRepeatCount(Animation.INFINITE);//Sets how many times the animation should be repeated.
rotateAnimation.setInterpolator(new LinearInterpolator());//Sets the acceleration curve for this animation.
ivLoading.startAnimation(rotateAnimation);
return rootView;
}
and in fragment_loading.xml file,
<ImageView
android:id="#+id/ivLoading"
android:layout_width="200px"
android:layout_height="200px"
android:layout_centerHorizontal="true"
android:src="#drawable/ic_rounded_loading"
android:layout_centerVertical="true" />
Runnable runnable = new Runnable() {
#Override
public void run() {
binding.progressImage.animate().rotationBy(360).withEndAction(this).setDuration(1500).setInterpolator(new LinearInterpolator()).start();
}
};
binding.progressImage.animate().rotationBy(360).withEndAction(runnable).setDuration(1500).setInterpolator(new LinearInterpolator()).start();

Apply two alternate rotations to a View in Android

I'd like to apply 2 alternate rotation animations to a View. Each rotation should start after the click on the same View.
The result I'm looking for is:
the user clicks on the View and it rotates from 0° to 135°
the user clicks again on the View and it rotates from 135° to 0° (to the initial state)
The problem is that, when the user performs the second click, the Button resets to the initial aspect before starting the animation correctly.
I'm targeting Android APIs<11 so I'm using the startAnimation() method. The animations are applied to a Button view defined as follows:
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
The animations are the following
rotate_cw.xml (0° to 135° rotation):
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<rotate
android:duration="300"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="135" />
</set>
rotate_ccw.xml (135° to 0° rotation):
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="300"
android:fromDegrees="135"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="0"/>
</set>
The animations are then applied in this way, where flag is a boolean global variable:
Button b = (Button) findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (flag) {
Animation a = AnimationUtils.loadAnimation(this, R.anim.rotate_cw);
b.startAnimation(a);
} else {
Animation a = AnimationUtils.loadAnimation(this, R.anim.rotate_ccw);
b.startAnimation(a);
}
flag = !flag;
}
});
Am I missing anything?
Thanks in advance for your help.

How to animate button in android?

I am making an android app, and I have a button which leads to a messaging place. On the activity with the button, I check if there is any unread messages, and if so I want to do something to the button to let the user know that there is something unread.
I was thinking of having the button sorta vibrate horizontally like 3 shakes every 2 or 3 seconds.
I know how to run a thread in the background which does something every x milliseconds. But what I don't know what to do is shake it horizontally 3 times.
Can anyone help with this?
I was thinking of using the sin function, for the animation, I can use output from a sin function to get values that go up and down, which I can set the horizontal position of the button... But this seems too extreme, is there a better way?
I can't comment on #omega's comment because I don't have enough reputation but the answer to that question should be something like:
shake.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="100" <!-- how long the animation lasts -->
android:fromDegrees="-5" <!-- how far to swing left -->
android:pivotX="50%" <!-- pivot from horizontal center -->
android:pivotY="50%" <!-- pivot from vertical center -->
android:repeatCount="10" <!-- how many times to swing back and forth -->
android:repeatMode="reverse" <!-- to make the animation go the other way -->
android:toDegrees="5" /> <!-- how far to swing right -->
Class.java
Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
view.startAnimation(shake);
This is just one way of doing what you want, there may be better methods out there.
create shake.xml in anim folder
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="10"
android:duration="1000"
android:interpolator="#anim/cycle" />
and cycle.xml in anim folder
<?xml version="1.0" encoding="utf-8"?>
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:cycles="4" />
now add animation on your code
Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
anyview.startAnimation(shake);
If you want vertical animation, change fromXdelta and toXdelta value to fromYdelta and toYdelta value
Class.Java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_with_the_button);
final Animation myAnim = AnimationUtils.loadAnimation(this, R.anim.milkshake);
Button myButton = (Button) findViewById(R.id.new_game_btn);
myButton.setAnimation(myAnim);
}
For onClick of the Button
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.startAnimation(myAnim);
}
});
Create the anim folder in res directory
Right click on, res -> New -> Directory
Name the new Directory anim
create a new xml file name it milkshake
milkshake.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="100"
android:fromDegrees="-5"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="10"
android:repeatMode="reverse"
android:toDegrees="5" />
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class HeightAnimation extends Animation {
protected final int originalHeight;
protected final View view;
protected float perValue;
public HeightAnimation(View view, int fromHeight, int toHeight) {
this.view = view;
this.originalHeight = fromHeight;
this.perValue = (toHeight - fromHeight);
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
view.getLayoutParams().height = (int) (originalHeight + perValue * interpolatedTime);
view.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
}
uss to:
HeightAnimation heightAnim = new HeightAnimation(view, view.getHeight(), viewPager.getHeight() - otherView.getHeight());
heightAnim.setDuration(1000);
view.startAnimation(heightAnim);
Dependency
Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}}
and then add dependency
dependencies {
compile 'com.github.varunest:sparkbutton:1.0.5'
}
Usage
XML
<com.varunest.sparkbutton.SparkButton
android:id="#+id/spark_button"
android:layout_width="40dp"
android:layout_height="40dp"
app:sparkbutton_activeImage="#drawable/active_image"
app:sparkbutton_inActiveImage="#drawable/inactive_image"
app:sparkbutton_iconSize="40dp"
app:sparkbutton_primaryColor="#color/primary_color"
app:sparkbutton_secondaryColor="#color/secondary_color" />
Java (Optional)
SparkButton button = new SparkButtonBuilder(context)
.setActiveImage(R.drawable.active_image)
.setInActiveImage(R.drawable.inactive_image)
.setDisabledImage(R.drawable.disabled_image)
.setImageSizePx(getResources().getDimensionPixelOffset(R.dimen.button_size))
.setPrimaryColor(ContextCompat.getColor(context, R.color.primary_color))
.setSecondaryColor(ContextCompat.getColor(context, R.color.secondary_color))
.build();
In Kotlin, this way after XML:
Define a View:
val playDel = findViewById<ImageView>(R.id.player_del)
Find a Animation: Here from Android Lib
val imgAnim = AnimationUtils.loadAnimation(this, android.R.anim.fade_out)
Connect to the View
playDel.animation=imgAnim
First create shake.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="100"
android:fromDegrees="-5"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="10"
android:repeatMode="reverse"
android:toDegrees="5" />
Class.java
Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
view.startAnimation(shake);

Categories

Resources