Button is not clickable after TranslateAnimation

I’m trying to move button (with animation) upon click. I want it to move 100 pixels to the bottom on first click, 100 pixels up on second, 100 pixels to the bottom on third and so on.
I have simple layout file (main.xml):

<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Press to begin animation" />

My launching activity is as follows:

  • dynamic alertdialog with radio buttons
  • What is the use of the res/values/public.xml file on Android?
  • What's the difference between using add().addToBackStack(), add().detach() and replace().addToBackStack() in a FragmentTransaction?
  • How well supported is pressure sensitivity across Android devices?
  • Android : how to know when an app enters or the “background” mode?
  • How to get profile picture in android using Twitter kit,
  • public class TestActivity extends Activity {
    public final String TAG="TestActivity";
    boolean toTop=false;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main); 
        Button b=(Button)findViewById(R.id.button);
        b.setOnClickListener(new OnClickListener() {
    
            public void onClick(View v) {
                Toast.makeText(TestActivity.this, "left="+v.getLeft()+"\nright="+v.getRight(), Toast.LENGTH_SHORT).show();
    
                Animation translateAnimation;
                if(toTop) translateAnimation=new TranslateAnimation(0, 0, 0, -100); 
                else translateAnimation=new TranslateAnimation(0, 0, 0, 100);
                translateAnimation.setDuration(1000);
                translateAnimation.setFillEnabled(true);
                translateAnimation.setFillAfter(true);
    
                v.startAnimation(translateAnimation);
                toTop=!toTop;
            }
        });
    }
    }
    

    When I press the button, I can see it moving to the bottom. But when I press it for the second time, nothing happens. I have to click to initial rectangle of the button to begin animation again. It seems like button is drawn as expected, but actual view is remained on the same position. I want to know how I can move a view entirely, not just its visual part.
    Besides, I use Toast.maketext.show to ensure that coordinates of the button aren’t changed from click to click.

    Related posts:

    Android: checkbox listener
    Android (Java) Real-time Audio Input (microphone AND USB) and Output
    Some Android devices extremely slow when rendering canvas elements
    Where do I get a google-services.json
    Make popup of the key pressed in a customized keyboard
    Using jobb tool in Android
  • Start another activity by clicking a button
  • Know if the app received the notification from server side
  • ActionBar Sherlock Menu Item OnClick
  • How to Hide keyboard when activity starts
  • onKeyDown() or onBackPressed()
  • Run multiple android app instances like parallel space
  • 4 Solutions collect form web for “Button is not clickable after TranslateAnimation”

    Yes, this is normal behavior. This is because animation just rerenders View‘s pixels, but it’s position on the display remains the same. If you want to relocate your View to the place where your animation ends, you need to call View.layout() method and pass there 4 parameters, which describe Views new position on it’s layout. Keep in mind that View.layout() gets params relative to Views parent.

    There is an easier way worth mentioning. One can use the View.animate() method which also moves the clickable elements:

    v.animate().translationY(100).start(); // move away
    v.animate().translationY(0).start(); // move back
    

    View.layout() really works, thanks a lot, teoREtik. Here I provide working variant, which moves the button itself (hope it will be useful for somebody):

    public class TestActivity extends Activity {
    public final String TAG="TestActivity";
    boolean toTop=false;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main); 
        Button b=(Button)findViewById(R.id.button);
        b.setOnClickListener(new OnClickListener() {
    
            public void onClick(View v) {
                int modifierY;
                if(toTop) modifierY=-100; 
                else modifierY=100;
                Animation translateAnimation=new TranslateAnimation(0, 0, 0, modifierY);
                translateAnimation.setDuration(1000);
                translateAnimation.setFillEnabled(true);
                MyAnimationListener listener=new MyAnimationListener(v, modifierY,TestActivity.this);
                translateAnimation.setAnimationListener(listener);
    
                v.startAnimation(translateAnimation);
                toTop=!toTop;
            }
        });
    }
    

    We have to invoke View.layout() only when animation is finished, so we need to use AnimationListener.onAnimationEnd. In order to be able to specify button and modifierY, I created my custom AnimationListener, which receives button and modifierY in constructor:

    public class MyAnimationListener implements AnimationListener{
    View mView;
    int mModifier;
    Context mContext;
    
    public MyAnimationListener(View v, int modifier, Context c){
        mView=v;
        mModifier=modifier;
        mContext=c;
    }
    public void onAnimationEnd(Animation animation) {
        int[] pos={mView.getLeft(),mView.getTop()+mModifier,mView.getRight(),mView.getBottom()+mModifier};
        mView.layout(pos[0],pos[1],pos[2],pos[3]);
        Toast.makeText(mContext, "left="+mView.getLeft()+"\ntop="+mView.getTop(), Toast.LENGTH_SHORT).show();
    }
    
    public void onAnimationRepeat(Animation animation) {}
    
    public void onAnimationStart(Animation animation) {}
    
    }
    

    An easy solution is to add padding in the onAnimationEnd function:

     public void moveAnimation() {
    
        move = new TranslateAnimation(Pos-50, 0, 0, 0);
        Pos += 50.0;
        move.setDuration(1500);
        move.setFillAfter(true);
         move.setAnimationListener(new AnimationListener(){
    
                @Override
                public void onAnimationEnd(Animation arg0) {
    
                    int x=(int) (Pos-50),y=0; 
                    i.setPadding(x,y,0,0);
                    x+=50; y+=0;
                    i.setPadding(x,y,0,0);
                }
    
                @Override
                public void onAnimationRepeat(Animation arg0) {
                    // TODO Auto-generated method stub
    
                }
    
                @Override
                public void onAnimationStart(Animation arg0) {
                    // TODO Auto-generated method stub
    
                }
    
            });
    
    
        i.startAnimation(move);
    
    
    }
    

    where i = (ImageView) findViewById(R.id.imgAMD);

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.