自定义TextView实现TextInputLayout式浮动标签动画的X轴平移问题
实现TextInputLayout同款浮动标签效果的解决方案
你遇到的核心问题是默认TextView的缩放锚点位于View中心,缩放时会向中心收缩,导致横向位置偏移、垂直平移计算不符合预期,以下是两种可行方案:
方案1:修改缩放锚点(推荐)
从根源避免缩放导致的位置偏移,无需额外计算X轴偏移量,适配任意文本长度:
- 初始化阶段仅需设置一次缩放枢轴点,注意要等View布局完成后再获取宽高:
tvHint.post(() -> { // X轴锚点设为左边缘,缩放时左侧位置保持固定,实现左对齐效果 tvHint.setPivotX(0f); // Y轴锚点设为View底部,缩放时底部位置保持固定 tvHint.setPivotY(tvHint.getHeight()); });
- 简化动画逻辑,删除X轴平移相关代码:
private void triggerAnimation(boolean fadeOut) { if (fadeOut) { // 上浮距离可根据业务需求调整,0.7f为参考值 tvHint.animate() .translationY(-tvHint.getHeight() * 0.7f) .scaleX(0.6f) .scaleY(0.6f) .setDuration(200); } else { tvHint.animate() .translationY(0) .scaleX(1f) .scaleY(1f) .setDuration(200); } }
如果需要右对齐效果,只需要把
setPivotX的参数改为tvHint.getWidth()即可,无需其他改动。
方案2:保留中心锚点,修正X偏移计算
如果你不能修改View的缩放锚点,修正之前的偏移量计算公式即可:
中心锚点下,缩放后左边缘会向右偏移 (原宽度 - 缩放后宽度)/2,向左平移同等距离即可保持左对齐,正确代码如下:
private void triggerAnimation(boolean fadeOut) { if (fadeOut) { float scale = 0.6f; float originTextWidth = tvHint.getPaint().measureText(tvHint.getHint().toString()); // 正确偏移量计算公式:(原宽度 - 缩放后宽度) / 2 float xTranslation = originTextWidth * (1 - scale) / 2; tvHint.animate() .translationY(-tvHint.getHeight() * 0.28f) .translationX(-xTranslation) .scaleX(scale) .scaleY(scale); } else { tvHint.animate() .translationY(0) .translationX(0) .scaleX(1f) .scaleY(1f); } }
注意事项
- 所有宽高、文本长度的计算必须在View布局完成后执行,不要在
onCreate/onCreateView中直接获取,否则会拿到0值,建议用post方法或者OnLayoutChangeListener监听布局完成回调。 - 上浮距离、缩放比例均可根据你的UI设计需求灵活调整。
内容的提问来源于stack exchange,提问作者Avinta
相关产品推荐
相关产品推荐

