Почему setVisibility не работает после анимации представления?

Почему textView не становится невидимым?

Вот мой макет xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
    android:id="@+id/tvRotate"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Rotate Me"
/>
</LinearLayout>

..и вот моя деятельность:

public class RotateMeActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView tvRotate = (TextView) findViewById(R.id.tvRotate);

        RotateAnimation r = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        r.setDuration(0);
        r.setFillAfter(true);
        tvRotate.startAnimation(r);
        tvRotate.setVisibility(View.INVISIBLE);
    }
}

Моя цель — повернуть представление, а затем скрыть и показать его в коде, установив setVisibility. Следующее работает, но setRotation доступен только на уровне API 11. Мне нужен способ сделать это на уровне API 10.

tvRotate.setRotation(180);//instead of the RotateAnimation, only works in API Level 11
tvRotate.setVisibility(View.INVISIBLE);

person ZippyFerguson    schedule 31.12.2011    source источник


Ответы (6)


Для меня вызов clearAnimation представления решил проблему. В моем случае я хотел вернуть View в исходное положение после выполнения перевода с fillAfter, установленным в true.

person Jeroen    schedule 27.03.2012
comment
У меня была эта проблема, и я могу подтвердить, что clearAnimation помогает. - person Christopher Perry; 23.08.2012
comment
пожалуйста, кто-нибудь примет этот ответ, так как он спасает вашу задницу после ДНЕЙ борьбы;) спасибо! - person Dale Cooper; 29.12.2013
comment
Я подтверждаю, что это решает проблему. Чтобы быть более полезным, используйте его в onAnimationEnd() в AnimationListener ;) - person czaku; 19.03.2014
comment
Кто-нибудь знает, зачем это нужно? Это устранило проблему, с которой я столкнулся, когда представление не удалялось из родителя. - person gak; 10.06.2014
comment
jtietema, было бы лучше, если бы вы добавили комментарий Чаку к своему ответу, спасибо. - person Buddy; 10.08.2015
comment
Вау... Я потратил столько времени, пытаясь понять это. Отличное (и загадочное) решение! - person bstar55; 22.06.2016
comment
Мое изменение видимости не работало в API 19 из-за TransitionManager.delayedTransition. Это была анимация на бегущей строке, которая вызывала это, и это исправило это. - person dbar; 25.05.2017

Все анимации (до Android 3.0) фактически применяются к растровому изображению, которое является снимком вашего представления, а не исходным представлением. Когда вы устанавливаете для заливки после значение true, это на самом деле означает, что растровое изображение будет продолжать отображаться на экране вместо вашего представления. Это причина, по которой видимость не изменится при использовании setVisibility, а также причина, по которой ваше представление не будет получать сенсорные события в своих новых (повернутых) границах. (но так как вы вращаетесь на 180 градусов, это не проблема).

person asenovm    schedule 31.12.2011
comment
Итак, есть ли способ скрыть растровое изображение, которое сохраняется после поворота? - person ZippyFerguson; 01.01.2012

Другой способ обойти это — поместить анимированный вид в другой вид и установить видимость этого вида-оболочки.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical" >
    <FrameLayout 
        android:id="@+id/animationHoldingFrame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
             android:id="@+id/tvRotate"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="Rotate Me"
        />
    </FrameLayout>
</LinearLayout>

И тогда код становится таким:

TextView tvRotate = (TextView) findViewById(R.id.tvRotate);
FrameLayout animationContainer = (FrameLayout)findViewById(R.id.animationHoldingFrame)

RotateAnimation r = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
r.setDuration(0);
r.setFillAfter(true);
tvRotate.startAnimation(r);
animationContainer.setVisibility(View.INVISIBLE);
person Chris Knight    schedule 25.02.2012
comment
Именно то, что я искал :-) - person Couitchy; 12.09.2016

Используйте это перед setVisibility после завершения анимации:

anim.reverse();
anim.removeAllListeners();
anim.end();
anim.cancel();

где anim - ваш ObjectAnimator

но если вы используете класс анимации, просто выполните:

view.clearAnimation();

на вид, на котором была выполнена анимация

person Community    schedule 20.05.2016

В итоге мне потребовался API уровня 11 и я использовал setRotation для этого. Это кажется довольно простым требованием, которое невозможно выполнить до Honeycomb. Все, что я хотел сделать, это повернуть кнопку, а затем скрыть/показать ее.

person ZippyFerguson    schedule 02.01.2012

Я придумал обходной путь для этого: в основном прямо перед тем, как вы вызываете setVisibility(View.GONE), сделайте анимацию с продолжительностью = 0 setFillAfter(false) и установите угол от/до до текущего угла поворота.

Это очистит растровое изображение setFillAfter и позволит исчезнуть представлению.

person Grantland Chew    schedule 25.01.2012