Android中RelativeLayout顶部滑入动画未生效问题求助
解决RelativeLayout从顶部滑入无动画的问题
嘿,我一眼就看出问题所在啦——你在onCreate里调用question_box.getHeight()的时候,这个布局还没完成测量和绘制呢!此时getHeight()返回的是0,所以你设置的translationY(-question_box.getHeight())其实等于translationY(0),相当于根本没把布局移到屏幕上方,后续的滑入动画自然就看不到效果了。
下面给你两个靠谱的修复方案:
方案一:监听布局完成事件,获取正确高度后设置初始偏移
我们可以用ViewTreeObserver来监听布局完成的时机,等布局真正测量好高度后,再把它移到屏幕外:
public class OverlayActivity extends Activity implements View.OnClickListener { RelativeLayout question_box; private boolean hasAnimated = false; // 标记动画是否已执行,避免重复触发 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_overlay); question_box = findViewById(R.id.question_box); question_box.setVisibility(View.INVISIBLE); // 先设置为不可见 // 监听布局完成事件,获取正确的高度 question_box.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 移除监听,防止重复触发 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { question_box.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { question_box.getViewTreeObserver().removeGlobalOnLayoutListener(this); } // 将布局移到屏幕上方 question_box.setTranslationY(-question_box.getHeight()); } }); final Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); } public void animateInObjects() { question_box.setVisibility(View.VISIBLE); question_box.animate().setDuration(1000).translationY(0); } @Override public void onClick(View v) { //Some Code } @Override protected void onStop() { super.onStop(); finish(); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); // 只在第一次获取焦点且未执行动画时触发 if (hasFocus && !hasAnimated) { animateInObjects(); hasAnimated = true; } } }
方案二:在动画前动态设置初始位置(更简洁)
如果不想用监听,也可以在执行滑入动画前,先把布局移到屏幕外,这里用post方法确保布局已经测量完成:
public void animateInObjects() { question_box.post(() -> { question_box.setVisibility(View.VISIBLE); // 先设置初始位置到屏幕上方 question_box.setTranslationY(-question_box.getHeight()); // 执行滑入动画 question_box.animate().setDuration(1000).translationY(0); }); }
同时记得给onWindowFocusChanged加个hasAnimated标记,避免Activity多次获取焦点时重复执行动画(比如锁屏后再解锁)。
额外注意点
- 确保布局的
android:visibility初始设置为invisible或者gone,避免一开始就显示出来 - 动画执行前一定要保证View已经完成测量,否则
getHeight()还是会返回0
内容的提问来源于stack exchange,提问作者Pam Ix
相关产品推荐
相关产品推荐

