Android中同时使用ViewPropertyAnimator缩放和平移时位置偏移问题
问题描述
需要实现将红色视图移动并缩放到紫色视图上方,使两者左上角精准对齐。
动画初始状态:
原实现代码:
View view = findViewById(R.id.test_image); View finalWrapper = findViewById(R.id.final_wrapper); float scale = new Random().nextFloat(); // 该缩放比例仅在运行时确定 view.animate().scaleX(scale).scaleY(scale) .translationX(finalWrapper.getLeft() - view.getLeft()) .translationY(finalWrapper.getTop() - view.getTop()) .setDuration(500).start();
问题现象:单独使用缩放或平移时代码运行正常,但同时使用两者时,红色视图无法精准对齐紫色视图的左上角,始终存在偏移:
仅使用平移时效果正常:
view.animate() .translationX(finalWrapper.getLeft() - view.getLeft()) .translationY(finalWrapper.getTop() - view.getTop()) .setDuration(500).start();
效果如下:
提问:如何在同时使用缩放和平移的情况下,让红色视图与紫色视图的左上角精准对齐?
解决方案
问题根源在于Android视图默认以中心作为缩放原点,缩放后视图的左上角会因为中心缩放产生偏移,原平移计算没有考虑这个偏移量,导致对齐误差。
有两种可行的修正方式:
方式一:调整平移计算量,抵消缩放偏移
计算缩放后视图左上角的偏移量,将其加入到平移值中:
View view = findViewById(R.id.test_image); View finalWrapper = findViewById(R.id.final_wrapper); float scale = new Random().nextFloat(); // 计算缩放后视图的尺寸变化 float scaledWidth = view.getWidth() * scale; float scaledHeight = view.getHeight() * scale; // 计算缩放导致的左上角偏移:原中心到左上角的距离,缩放后与原距离的差值 float offsetX = (view.getWidth() - scaledWidth) / 2; float offsetY = (view.getHeight() - scaledHeight) / 2; // 最终平移量 = 目标与原位置的差值 + 缩放偏移量 float translateX = finalWrapper.getLeft() - view.getLeft() + offsetX; float translateY = finalWrapper.getTop() - view.getTop() + offsetY; view.animate() .scaleX(scale) .scaleY(scale) .translationX(translateX) .translationY(translateY) .setDuration(500) .start();
方式二:修改缩放原点为左上角(更简洁)
直接将视图的缩放原点设置为左上角,这样缩放操作不会改变左上角的相对位置,原平移逻辑即可直接生效:
View view = findViewById(R.id.test_image); View finalWrapper = findViewById(R.id.final_wrapper); float scale = new Random().nextFloat(); // 设置缩放原点为视图左上角 view.setPivotX(0); view.setPivotY(0); view.animate() .scaleX(scale) .scaleY(scale) .translationX(finalWrapper.getLeft() - view.getLeft()) .translationY(finalWrapper.getTop() - view.getTop()) .setDuration(500) .start();
推荐使用方式二,代码更简洁且逻辑直观,无需额外计算偏移量。
内容的提问来源于stack exchange,提问作者L. Swifter
相关产品推荐
相关产品推荐

