web-dev-qa-db-ja.com

ビューがアニメーション化された後に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);
63
ZippyFerguson

ビューのclearAnimationを呼び出すと、問題が修正されました。私の場合、fillAfterをtrueに設定して変換を行った後、ビューを元の位置に戻したいと思いました。

161
Jeroen

すべてのアニメーション(Android 3.0)より前)は、元のビューではなく、ビューのスナップショットであるビットマップに実際に適用されます。fillafterをtrueに設定すると、実際にはビューの代わりにビットマップが画面に表示され続けるこれが、setVisibilityを使用しても可視性が変わらない理由であり、ビューが新しいイベントでタッチイベントを受け取らない理由でもあります(回転)境界(ただし、180度回転しているので問題ありません)。

21
asenovm

これを回避する別の方法は、アニメーションビューを別のビューでラップし、そのラッパービューの可視性を設定することです。

<?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);
8
Chris Knight

アニメーションが完了した後、setVisibilityの前にこれを使用します。

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

ここで、animはObjectAnimatorです

ただし、Animationクラスを使用している場合は、次のようにします。

view.clearAnimation();

アニメーションが実行されたビューで

6
user3567365

APIレベル11が必要になり、setRotationを使用してこれを達成しました。これは、ハニカム前にはできない非常に単純な要件のようです。やりたかったのは、ボタンを回転させてから非表示/表示することだけでした。

1
ZippyFerguson

私はこれに対する回避策を思いつきました:基本的にsetVisibility(View.GONE)を呼び出す直前に、duration = 0でアニメーションを実行し、setFillAfter(false)を設定し、現在の回転角度を設定します。

これにより、setFillAfterビットマップがクリアされ、ビューが消えます。

1
Grantland Chew