Кнопка не может быть нажата после 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);