animation in android - android

I had an activity (say homeActivity) and when I start a new activity(say nextActivity) from my homeactivity i would like to give it an animation effect like appearing it from the bottom. Is it possible in android?

after call to startActivity, make call to overridePendingTransition with id's of xml defined animations, one for exiting activity, one for entering. See docs for this method here

You can prevent the default animation (Slide in from the right) with the Intent.FLAG_ACTIVITY_NO_ANIMATION flag in your intent.
i.e.:
Intent myIntent = new Intent(context, MyActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
context.startActivity(myIntent);
then in your Activity you simply have to specify your own animation.

TopListActivity topList;
Vector<BitmapDrawable> images;
int count = 0;
public AnimationAlphaTimer(TopListActivity _topList)
{
this.topList = _topList;
this.images = new Vector<BitmapDrawable>();
for (int i = 0; ; i++) {
// LOAD IMAGES HERE
}
if (this.images.size() > 0) {
this.topList.slide_0.setBackgroundDrawable(this.images.get(0));
if (this.images.size() > 1) {
this.topList.slide_1.setBackgroundDrawable(this.images.get(1));
}
}
this.count = 1;
}
public void launch()
{
if (this.images.size() >= 2) {
(new Timer(false)).schedule(this, 100);
}
}
#Override
public void run()
{
this.doit();
this.cancel();
}
private void doit()
{
if ((this.count % 2) == 0) {
AlphaAnimation animation = new AlphaAnimation(1.0f, 0.0f);
animation.setStartOffset(3000);
animation.setDuration(3000);
animation.setFillAfter(true);
animation.setAnimationListener(this);
this.topList.slide_1.startAnimation(animation);
} else {
AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setStartOffset(3000);
animation.setDuration(3000);
animation.setFillAfter(true);
animation.setAnimationListener(this);
this.topList.slide_1.startAnimation(animation);
}
}
public void onAnimationEnd(Animation animation)
{
if ((this.count % 2) == 0) {
this.topList.slide_1.setBackgroundDrawable(
this.images.get((this.count + 1) % (this.images.size()))
);
} else {
this.topList.slide_0.setBackgroundDrawable(
this.images.get((this.count + 1) % (this.images.size()))
);
}
this.count++;
this.doit();
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}}
try this i think it will work.

Related

How to stop an animation onBackPressed?

In my MainActivity I have 2 animations (FAB and a TAB title) and I would like to stop them onBackPressed.
#Bind(R.id.fab_text) Button mFAB;
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_drawer);
Animation animation = loadAnimation(MainDrawerActivity.this, R.anim.fab_scale_up_down);
animation.setRepeatCount(Animation.INFINITE);
animation.setAnimationListener(new SimpleAnimationListener() {
private long offset;
private long startTime;
#Override
public void onAnimationStart(Animation animation) {
startTime = System.currentTimeMillis();
}
#Override
public void onAnimationRepeat(Animation animation) {
final long now = System.currentTimeMillis();
Timber.i("onAnimationRepeatFAB: elapeed seconds: %d", (now - startTime) / 1000);
if ((now - startTime > 7000) && (offset % 4 == 0)) { // stop animation after X seconds
animation.setRepeatCount(0);
} else {
offset++;
animation.setStartOffset(offset % 4 == 0 ? 700 : 0);
}
}
});
mFAB.startAnimation(animation);
About the FAB it's easy.
public void onBackPressed() {
mFAB.clearAnimation();
But how do I stop the other animation defined like this? I don't know how to access the animation of the TAB below.
private void populateViewPager(List<Tab> tabs) {
// clear all listeners before populating new tabs
mTabLayout.setOnTabSelectedListener(null);
mViewPager.clearOnPageChangeListeners();
if (mPagerAdapter == null) {
mPagerAdapter = new TabsPagerAdapter(this, getSupportFragmentManager());
mViewPager.setAdapter(mPagerAdapter);
}
// populate tabs
mPagerAdapter.setTabs(tabs);
if (mPagerAdapter.getCount() > DEFAULT_TAB_POSITION)
mViewPager.setCurrentItem(DEFAULT_TAB_POSITION);
mTabLayout.setupWithViewPager(mViewPager);
// set animation on corresponding tabs
List<Tab> pagerTabs = mPagerAdapter.getTabs();
for (int i = 0; i < pagerTabs.size(); i++) {
Tab pagerTab = pagerTabs.get(i);
if (pagerTab.isAnimated()) {
Timber.i("Animating tab: %s", pagerTab.getId());
TabLayout.Tab tab = mTabLayout.getTabAt(i);
if (tab != null) {
// set custom view in order to get it back then
tab.setCustomView(R.layout.partial_tab_view);
// set animation on the custom view
Animation animation = loadAnimation(MainDrawerActivity.this, R.anim.tab_scale_up_down);
animation.setRepeatCount(Animation.INFINITE);
animation.setAnimationListener(new SimpleAnimationListener() {
private long offset;
private long startTime;
#Override
public void onAnimationStart(Animation animation) {
startTime = System.currentTimeMillis();
}
#Override
public void onAnimationRepeat(Animation animation) {
final long now = System.currentTimeMillis();
Timber.i("onAnimationRepeat: elapeed seconds: %d", (now - startTime) / 1000);
if ((now - startTime > 7000) && (offset % 4 == 0)) { // stop animation after X seconds
animation.setRepeatCount(0);
} else {
offset++;
animation.setStartOffset(offset % 4 == 0 ? 700 : 0);
}
}
});
//noinspection ConstantConditions
tab.getCustomView().setAnimation(animation);
} else {
Timber.w("tab!=null");
}
}
}
}
Declare an Animation object as a global variable. Use cancel() method to cancel the animation.
Try this:
// Animation
Animation animation;
............
..............
private void populateViewPager(List<Tab> tabs) {
.................
..............................
animation = AnimationUtils.loadAnimation(MainDrawerActivity.this, R.anim.tab_scale_up_down);
..............
.....................
}
#Override
public void onBackPressed() {
animation.cancel();
super.onBackPressed();
}
Store a reference to your Animation, then call cancel() on the Animation.
The other answers about saving the animation as an object variable, will not work in your code, as you are creating a separate animation for each tab.
Having said that, the fact that you are creating animations for tabs that are not visible, is a huge waste of resources.
Change your code, add a pager listener, and set animation only on current page. Do that by creating single Animation object variable, attach it to current view. When page changes, cancel it, destroy it, and create new one for current page (not sure if you can reuse the old one). Now that you have a single Animation variable, you can also cancel it in onBackPressed.

Change Image when repeat animation

I would like to rotate an imageView 10 times, every times, the imageView will load randomly an image in drawable resources. For example: there are 6 images like img1 to img6. I did the code like this, but it doesn't work
public void clockwise(View view){
for (int i=1; i<=6; i++){
ImageView image = (ImageView)findViewById(R.id.imageView);
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.clockwise);
animation.setRepeatCount(10);
int max=6, min=1;
int randNum = min + (int)(Math.random()*((max-min)+1));//
if (randNum==1) image.setImageDrawable(getResources().getDrawable(R.drawable.die1));
else if (randNum==2) image.setImageDrawable(getResources().getDrawable(R.drawable.die2));
else if (randNum==3) image.setImageDrawable(getResources().getDrawable(R.drawable.die3));
else if (randNum==4) image.setImageDrawable(getResources().getDrawable(R.drawable.die4));
else if (randNum==5) image.setImageDrawable(getResources().getDrawable(R.drawable.die5));
else if (randNum==6) image.setImageDrawable(getResources().getDrawable(R.drawable.die6));
image.startAnimation(animation);
}
It just load only one image that I set in xml file for 10 times of repeating
you can use animation listener like below
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});)
So in onAnimationRepeat method you can change your image.
instead of loop use Animation Listener.
ImageView image = (ImageView)findViewById(R.id.imageView);
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.clockwise);
animation.setRepeatCount(10);
image.startAnimation(animation);
Overrided methods.
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
int max=6, min=1;
int randNum = min + (int)(Math.random()*((max-min)+1));//
if (randNum==1) image.setImageDrawable(getResources().getDrawable(R.drawable.die1));
else if (randNum==2) image.setImageDrawable(getResources().getDrawable(R.drawable.die2));
else if (randNum==3) image.setImageDrawable(getResources().getDrawable(R.drawable.die3));
else if (randNum==4) image.setImageDrawable(getResources().getDrawable(R.drawable.die4));
else if (randNum==5) image.setImageDrawable(getResources().getDrawable(R.drawable.die5));
else if (randNum==6) image.setImageDrawable(getResources().getDrawable(R.drawable.die6));
}
Thanks KDeogharkar and Ragesh for your suggestion.
I've tried to used your way that is changing image onAnimationRepeat(), but it still doesn't work. I guess that is caused because the image is still being used by the animation, so it doesn't allow to change the image. Therefore, I write a recursive function that waits for the end of the animation to change image, and call the same animation, so finally it works. Here is my code
public void rotate(int count){
//
final int nextCount = count - 1;
ImageView image = (ImageView)findViewById(R.id.imageView);
int max = 6, min = 1;
int randNum = min + (int) (Math.random() * ((max - min) + 1));//
if (randNum == 1)
image.setImageDrawable(getResources().getDrawable(R.drawable.die1));
else if (randNum == 2)
image.setImageDrawable(getResources().getDrawable(R.drawable.die2));
else if (randNum == 3)
image.setImageDrawable(getResources().getDrawable(R.drawable.die3));
else if (randNum == 4)
image.setImageDrawable(getResources().getDrawable(R.drawable.die4));
else if (randNum == 5)
image.setImageDrawable(getResources().getDrawable(R.drawable.die5));
else if (randNum == 6)
image.setImageDrawable(getResources().getDrawable(R.drawable.die6));
Animation animation;
animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.clockwise);
animation.setRepeatCount(1);
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
if (nextCount >=0) rotate(nextCount);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
image.startAnimation(animation);
}
After that, I just need to call rotate(animationTimes) in main() function.

How to change android background every ??? seconds?

I want to change my Relative layout's background every 10 seconds with fade in/fade out animation.
So I found
//Transitiondrawable
TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
transition.startTransition(transitionTime);
But it supports only 2 Drawable and I want to add more
Is there any way to do this?
First implement MyAnim.java class as below:
public class MyAnim extends Animation {
private final RelativeLayout view;
private int targetBackGround;
public MyAnim(RelativeLayout view, int tagetBackGroundColor) {
this.view = view;
this.targetBackGround = tagetBackGroundColor;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
view.setBackgroundColor(targetBackGround);
}
public void setColor(int color) {
this.targetBackGround = color;
}
}
Then add below code to your activity and call that animateBackground() method wherever you want:
private MyAnim backgroundAnim;
private int i;
private void animateBackground(){
final RelativeLayout animLay = (RelativeLayout) findViewById(R.id.animLay);
final int colors[] = new int[]{Color.RED, Color.CYAN, Color.DKGRAY, Color.GREEN, Color.MAGENTA};
backgroundAnim = new MyAnim(animLay, colors[i]);
backgroundAnim.setDuration(1000);
animLay.startAnimation(backgroundAnim);
backgroundAnim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
if (i == colors.length - 1) {
i = 0;
} else {
i++;
}
backgroundAnim.setColor(colors[i]);
animLay.startAnimation(backgroundAnim);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
You can create your own loop, something like:
int delayBetweenAnimations = 10000;
for (int i = 0; i < yourImagesArray.length ; i++) {
int delay = i * delayBetweenAnimations;
yourImageview.postDelayed(new Runnable() {
#Override
public void run() {
//set your image and animation here
}
}, delay);
}
Another way is to use recursive animation:
#Override
public void onAnimationEnd(Animator animation) {
if(check_if_you_Still_want to_loop){
//rerun your animation
}
}

Android Viewpager bounce to half a page

So what i am trying to achieve is user would open to first page of the view pager, and the view pager would bounce to half of the second page and bounce back to the fist page indicating that there are more pages to scroll to. I was wondering on how i could implement this?
You can use fakeDragBy method to achieve this effect:
viewPager.beginFakeDrag();
viewPager.fakeDragBy(offset); //offset in pixels.
viewPager.endFakeDrag();
EDIT:
I have made method for this:
private int animFactor;
private ValueAnimator animator = new ValueAnimator();
private void animateViewPager(final ViewPager pager, final int offset, final int delay) {
if (!animator.isRunning()) {
animator.removeAllUpdateListeners();
animator.removeAllListeners();
//Set animation
animator.setIntValues(0, -offset);
animator.setDuration(delay);
animator.setRepeatCount(1);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = animFactor * (Integer) animation.getAnimatedValue();
if (!pager.isFakeDragging()) {
pager.beginFakeDrag();
}
pager.fakeDragBy(value);
}
});
animator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationStart(Animator animation) {
animFactor = 1;
}
#Override
public void onAnimationEnd(Animator animation) {
pager.endFakeDrag();
}
#Override
public void onAnimationRepeat(Animator animation) {
animFactor = -1;
}
});
animator.start();
}
}
Example of usage:
animateViewPager(pager, 10, 1000);
Edit2: ValueAnimator is class for Api level 11. Also set pager adapter before calling this method.
Adding a note to #Yuraj's answer. Call the method in onWindowFocusChanged when hasFocus==true as follows to avoid indexOutOfBoundsException:
#Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
if(hasFocus)
{
Handler handler = new Handler();
final Runnable r = new Runnable()
{
public void run()
{
if(mViewPager.getCurrentItem() == 0)
{
Context context = Activity_main.this;
String filename="Init";
SharedPreferences stats;
stats = context.getSharedPreferences(filename, 0);
int appOpen = stats.getInt("appOpen", 0);
if(appOpen <= 5)
{
animateViewPager(mViewPager, 10, 300);
appOpen += 1;
SharedPreferences.Editor editor = stats.edit();
editor.putInt("appOpen", appOpen);
editor.commit();
}
}
}
};
handler.postDelayed(r, WAIT_VIEWPAGER_NUDGE);
}
}
Thank you Yuvraj! It worked with a simple modification. If anybody is getting "Invalid index 0, size is 0" error, here's a simple fix for it. If you call animateViewPager() method in onCreate() you might get this error, "Invalid index 0, size is 0". I believe viewpager.beginFakeDrag(); is being called before viewPager items / childs are initialized. So, call animateViewPager() with a delay like so:
new Handler().postDelayed(() -> animateViewPager(viewPager, 10, 1000), 500);
500 is the delay in milisecond

Animation starts only when I touch the screen

I have a listview with entries which have a fade out animation when the user deletes\edits an entry in the list.
For some reason, after I perform the action (edit\delete) the animation will not start until I press the screen again. Only they will the animation actually perform.
From this method the animation is being called:
public void replace(View view, long position) {
int hoursSum = 0;
int minuteSum = 0;
boolean hoursIssue = false;
if (finsihIntMinutes >= startIntMinutes) {
minuteSum = finsihIntMinutes - startIntMinutes;
} else if (finsihIntMinutes < startIntMinutes) {
minuteSum = (finsihIntMinutes + Utility.MINUTES_TIME_UNIT)
- startIntMinutes;
hoursIssue = true;
}
if (finishIntHours >= startIntHours) {
hoursSum = finishIntHours - startIntHours;
if (hoursIssue == true) {
--hoursSum;
}
} else if (finishIntHours < startIntHours) {
hoursSum = (finishIntHours + Utility.HOURS_TIME_UNIT)
- startIntHours;
}
double salper = (minuteSum * Main.sal) / 60;
double salper2 = hoursSum * (Main.sal);
String madeSoFar = ""
+ String.valueOf(formatter.format(salper2 + salper));
String edited = "**Edited**";
String totalTime = "" + hoursSum + ":" + minuteSum;
DB.edit(position, Shifts.editDate, Shifts.editStartTime,
Shifts.editEndTime, Shifts.dayString, totalTime, minuteSum,
madeSoFar, edited, totalHours, totalMinutes);
moneySummary = getMoney();
hoursSummary = "Total Hours: " + getHours();
summary.setText(moneySummary);
**FastScrollAdapter.animate(Shifts.view);**
}
Here is the animation code:
public static void animate(final View v) {
Animation out = new AlphaAnimation(1, 0);
out.setInterpolator(new DecelerateInterpolator());
out.setDuration(350);
v.setAnimation(out);
out.start();
out.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.i("Animation", "Started");
}
#Override
public void onAnimationRepeat(Animation animation) {
// Shifts.setSummaryCursor.requery();
Shifts.getMoneyCursor.requery();
FastScrollAdapter.cursor.requery();
Shifts.CA.notifyDataSetChanged();
}
#Override
public void onAnimationEnd(Animation animation) {
// Shifts.setSummaryCursor.requery();
Shifts.getMoneyCursor.requery();
FastScrollAdapter.cursor.requery();
Shifts.CA.notifyDataSetChanged();
Log.i("Animation", "Ended");
}
});
}
I had exactly the same problem, I solved it by calling
view.clearAnimation();
just before
view.startAnimation(animation);
I think you need to change the order
1. v.setAnimation(out);
2. out.setAnimationListener(new AnimationListener());
3. v.startAnimation(out);
I had a similar problem: the animation was not performet in the UE thread. Try to run the animation posting it in the UE thead:
mHandler.post(new Runnable() {
#Override
public void run() {
yourView.startAnimation(yourAnimation));
}
});

Categories

Resources