EditText点击扩展需求:输入时全屏宽度,失焦恢复原尺寸求方案
解决EditText点击展开全屏宽度、点击外部恢复的问题
嘿,我完全懂你遇到的困扰——你用ScaleAnimation做的展开动画只是视觉上的临时效果,动画结束后EditText会因为没真正修改布局参数而缩回去。咱们得把动画过渡和实际布局调整结合起来,再加上外部点击的判断逻辑,就能实现类似移动端浏览器地址栏的效果啦。
核心问题拆解
ScaleAnimation仅仅是对View做绘制层面的缩放,不会改变View本身的LayoutParams。所以动画一结束,系统就会按照原来的布局规则重新渲染View,导致它回到初始尺寸。我们需要在动画结束后真正修改EditText的宽度,同时处理外部点击的触发逻辑。
完整解决方案代码
下面是修改后的Home Activity代码,包含展开动画、布局参数永久修改、外部点击恢复的完整逻辑:
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.ScaleAnimation; import android.widget.EditText; import android.widget.RelativeLayout; public class Home extends AppCompatActivity { private EditText search_bar; // 保存EditText的初始宽度,用于后续恢复 private int originalWidth; // 标记当前是否处于展开状态,避免重复触发动画 private boolean isExpanded = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); search_bar = findViewById(R.id.search_bar); // 必须等布局加载完成后再获取初始宽度,用post确保时机正确 search_bar.post(() -> originalWidth = search_bar.getWidth()); // 设置EditText点击事件,触发展开逻辑 search_bar.setOnClickListener(v -> { if (!isExpanded) { expandEditText(); } }); } // 展开EditText至全屏宽度的方法 private void expandEditText() { int screenWidth = getResources().getDisplayMetrics().widthPixels; // 计算横向缩放比例:屏幕宽度 / 原始宽度 float scaleX = (float) screenWidth / originalWidth; // 创建缩放动画,以EditText左侧为原点横向缩放 ScaleAnimation scaleAnimation = new ScaleAnimation(1f, scaleX, 1f, 1f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0.5f); scaleAnimation.setDuration(750); // 动画结束后修改布局参数,让宽度永久变为屏幕宽度 scaleAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) search_bar.getLayoutParams(); params.width = screenWidth; search_bar.setLayoutParams(params); isExpanded = true; // 可选:让EditText自动获取焦点并弹出软键盘 search_bar.requestFocus(); } @Override public void onAnimationRepeat(Animation animation) {} }); search_bar.startAnimation(scaleAnimation); } // 恢复EditText至初始尺寸的方法 private void collapseEditText() { if (!isExpanded) return; float scaleX = (float) originalWidth / getResources().getDisplayMetrics().widthPixels; // 创建反向缩放动画 ScaleAnimation scaleAnimation = new ScaleAnimation(1f, scaleX, 1f, 1f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0.5f); scaleAnimation.setDuration(750); // 动画结束后恢复初始布局参数 scaleAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) search_bar.getLayoutParams(); params.width = originalWidth; search_bar.setLayoutParams(params); isExpanded = false; // 可选:清除焦点并收起软键盘 search_bar.clearFocus(); } @Override public void onAnimationRepeat(Animation animation) {} }); search_bar.startAnimation(scaleAnimation); } // 重写Activity触摸事件,判断是否点击了EditText外部 @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (!isPointInView(search_bar, event.getRawX(), event.getRawY())) { collapseEditText(); } } return super.onTouchEvent(event); } // 辅助方法:判断触摸点是否在指定View范围内 private boolean isPointInView(View view, float rawX, float rawY) { int[] location = new int[2]; view.getLocationOnScreen(location); int left = location[0]; int top = location[1]; int right = left + view.getWidth(); int bottom = top + view.getHeight(); return rawX >= left && rawX <= right && rawY >= top && rawY <= bottom; } }
关键细节说明
- 初始宽度获取:用
search_bar.post()确保布局完全加载后再获取宽度,避免拿到0值。 - 动画+布局修改结合:动画负责平滑过渡,动画结束后修改
LayoutParams让宽度永久改变,这样就不会再自动恢复了。 - 外部点击判断:通过
onTouchEvent结合isPointInView方法,精准判断点击位置是否在EditText之外,触发恢复逻辑。 - 状态标记:
isExpanded变量避免重复触发展开/恢复动画,提升交互流畅性。
布局适配提示
如果你的EditText父布局不是RelativeLayout,需要把代码中的RelativeLayout.LayoutParams替换成对应布局的参数类型(比如LinearLayout.LayoutParams),确保宽度修改生效。
内容的提问来源于stack exchange,提问作者EquiWare
相关产品推荐
相关产品推荐

