Кнопка не может быть нажата после TranslateAnimation

Я пытаюсь переместить кнопку (с анимацией) после клика. Я хочу, чтобы он переместил 100 пикселей в нижнюю часть первого щелчка, 100 пикселей вверх на секунду, 100 пикселей на нижнюю треть и так далее. У меня есть простой файл макета (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" />

Моя стартовая активность выглядит следующим образом:

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;
        }
    });
}
}

Когда я нажимаю кнопку, я вижу, как она перемещается на дно. Но когда я нажимаю его во второй раз, ничего не происходит. Я должен щелкнуть до начального прямоугольника кнопки, чтобы снова начать анимацию. Кажется, что кнопка нарисована так, как ожидалось, но фактический вид остается на той же позиции. Я хочу знать, как я могу полностью переместить взгляд, а не только его визуальную часть. Кроме того, я использую Toast.maketext.show, чтобы гарантировать, что координаты кнопки не будут изменены с момента щелчка.

Ответы

Ответ 1

Да, это нормальное поведение. Это связано с тем, что анимация просто воспроизводит пиксели View, но позиция на дисплее остается неизменной. Если вы хотите переместить ваш View в место окончания вашей анимации, вам нужно вызвать метод View.layout() и передать там 4 параметра, которые описывают View новую позицию на макете. Имейте в виду, что View.layout() получает параметры относительно родителя View.

Ответ 2

Существует более простой способ упомянуть. Можно использовать метод View.animate(), который также перемещает элементы, которые можно щелкнуть:

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

Ответ 3

View.layout() действительно работает, спасибо много, teoREtik. Здесь я предоставляю рабочий вариант, который перемещает сама кнопку (надеюсь, что это будет полезно для кого-то):

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;
        }
    });
}

Мы должны вызывать View.layout() только после завершения анимации, поэтому нам нужно использовать AnimationListener.onAnimationEnd. Чтобы иметь возможность указывать кнопку и модификаторY, я создал свой пользовательский AnimationListener, который получает кнопку и модификаторY в конструкторе:

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) {}

}

Ответ 4

Простым решением является добавление дополнения в функцию onAnimationEnd:

 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);


}

где i = (ImageView) findViewById(R.id.imgAMD);