現象:對正在運行 RotateAnimation 的 TextView 調用 setVisibility(View.INVISIBLE) 無效,View 仍可見。API 11+ setRotation() 正常。
Animation.setFillAfter(true) 保持動畫末幀狀態,**覆蓋** View 自身的可見性屬性。View.getVisibility()。View.setRotation() 修改 View 固有屬性,不涉及 Animation,故 setVisibility 生效。在目標 View 外層包一層 FrameLayout,隱藏容器而非 View 本身:
<FrameLayout
android:id="@+id/animContainer"
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>
TextView tv = findViewById(R.id.tvRotate);
FrameLayout container = findViewById(R.id.animContainer);
RotateAnimation anim = new RotateAnimation(0, 180,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(0); anim.setFillAfter(true);
tv.startAnimation(anim);
// 隱藏容器,動畫隨容器消失
container.setVisibility(View.INVISIBLE);
tv.clearAnimation(); // 關鍵:移除 Animation 對 View 的控制
tv.setVisibility(View.INVISIBLE);
缺點:動畫狀態(旋轉角度)丟失。
tv.animate().rotation(180).setDuration(300).start();
// 隨時可見性控制
tv.setVisibility(View.INVISIBLE); // 生效
// 或動畫結束後自動隱藏
tv.animate().rotation(180).setDuration(300)
.withEndAction(() -> tv.setVisibility(View.INVISIBLE))
.start();
tv.setLayerType(View.LAYER_TYPE_HARDWARE, null);
// 動畫運行在獨立 GPU 層,不影響主 View 可見性
tv.setVisibility(View.INVISIBLE); // 可能生效,視具體情況
tv.setLayerType(View.LAYER_TYPE_NONE, null); // 動畫結束後恢復
| 場景 | 推薦方案 |
|---|---|
| 需保持動畫末幀狀態且隱藏 | 方案一(包裝容器) |
| API 11+ 新項目 | 方案三(ViewPropertyAnimator) |
| 舊項目快速修復 | 方案二(clearAnimation) |
理解 Animation 與 View 可見性的競爭關係,選擇合適隔離策略。