如何获取动画视图的位置?TextView移动动画的位置监测与坐标判断
嘿,针对你关于TextView动画的两个问题,我来给你唠唠实操思路:
问题一:每隔1毫秒获取TextView的实时位置是否可行?
咱得先明确一个核心点:Android的UI刷新是基于VSYNC信号的,正常情况下每16ms左右刷新一帧(对应60fps)。你想每隔1ms就获取一次位置,从技术实现上来说,硬写个Timer或者Handler.postDelayed循环1ms确实能执行,但会有两个致命问题:
- 系统根本跟不上这么高的频率,大部分的位置获取操作都会得到重复的结果,因为UI还没来得及更新;
- 高频的循环会疯狂占用CPU资源,导致动画卡顿、APP响应变慢,严重的甚至会触发ANR(应用无响应)。
所以更合理的方案是绑定动画的帧更新回调,在动画的每一帧刷新时获取位置,这既符合Android的刷新机制,又能拿到最准确的实时位置。比如用ValueAnimator或者ObjectAnimator的addUpdateListener:
ObjectAnimator animator = ObjectAnimator.ofFloat(textView, "translationX", 0, 500); animator.setDuration(1000); animator.addUpdateListener(animation -> { // 在每一帧更新时获取位置 float currentX = textView.getX(); float currentY = textView.getY(); // 这里处理位置逻辑 }); animator.start();
问题二:如何检测TextView是否越过了指定固定坐标?
这个需求可以直接和上面的帧更新回调结合起来,在每一次获取实时位置后,和你指定的坐标做对比就行。需要注意的是,要先明确坐标的参考系:
getX()/getY():相对于父布局的左上角坐标;getRawX()/getRawY():相对于屏幕的左上角坐标(需要通过View.getLocationOnScreen()转换)。
举个例子,假设我们要检测TextView是否越过了父布局里的targetX = 300这个坐标:
float targetX = 300f; // 指定的固定X坐标 animator.addUpdateListener(animation -> { float currentX = textView.getX(); // 判断是否越过目标坐标(这里以向右越过为例,根据需求调整判断逻辑) if (currentX > targetX) { // 触发越过坐标后的逻辑,比如停止动画、弹出提示等 animator.cancel(); Toast.makeText(context, "已越过指定坐标", Toast.LENGTH_SHORT).show(); } });
如果是想在动画结束后再做一次性检测,也可以用动画的addListener:
animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationEnd(Animator animation) { float currentX = textView.getX(); if (currentX > targetX) { // 处理动画结束后的越界逻辑 } } // 其他三个方法按需实现,空实现也可以 @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} });
内容的提问来源于stack exchange,提问作者Shadab Aazam
相关产品推荐
相关产品推荐

