如何解决ScrollView中子控件EditText获焦时滚动至顶部的问题?
解决ScrollView在EditText获焦时跳回顶部的问题
这个问题我之前也碰到过,核心原因是你用setX()和setY()来定位EditText,而不是通过RelativeLayout的布局参数设置位置——Android的滚动系统是基于视图的布局位置计算滚动目标的,setX/Y只是视图绘制层的偏移,ScrollView没法正确识别EditText的实际位置,所以一获焦就默认滚回顶部了。下面给你两种可行的解决方案:
方案1:改用RelativeLayout布局参数定位EditText
把setX()和setY()替换成RelativeLayout.LayoutParams的margin设置,让布局系统能正确识别EditText的位置:
修改你的MyView类代码:
public class MyView extends RelativeLayout{ public MyView(Context context){ super(context); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 3000); setLayoutParams(lp); setBackgroundColor(0xddeeeeee); EditText editText = new EditText(getContext()); // 使用RelativeLayout的LayoutParams来设置位置和大小 RelativeLayout.LayoutParams editLp = new RelativeLayout.LayoutParams(150, 150); editLp.leftMargin = 200; // 对应原来的setX(200) editLp.topMargin = 400; // 对应原来的setY(400) editText.setLayoutParams(editLp); editText.setBackgroundColor(0xff0000aa); addView(editText); } }
这样修改后,ScrollView就能正确计算EditText的布局位置,获焦时会滚动到EditText所在的位置,而不是跳回顶部。
方案2:自定义ScrollView阻止自动滚动
如果你一定要保留setX/Y的定位方式,可以自定义ScrollView,重写requestChildFocus方法,阻止它自动滚动:
public class NoAutoScrollScrollView extends ScrollView { public NoAutoScrollScrollView(Context context) { super(context); } public NoAutoScrollScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public NoAutoScrollScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void requestChildFocus(View child, View focused) { // 不调用父类的requestChildFocus,阻止自动滚动 // super.requestChildFocus(child, focused); } }
然后在MainActivity里替换原来的ScrollView:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final LinearLayout listView = (LinearLayout) findViewById(R.id.project_list); NoAutoScrollScrollView scrollView = new NoAutoScrollScrollView(getApplicationContext()); MyView view = new MyView(getApplicationContext()); scrollView.addView(view); listView.addView(scrollView); } }
这个方法会完全禁用ScrollView的自动滚动行为,EditText获焦时ScrollView会保持当前位置,但缺点是EditText如果不在可视区域内,用户也看不到它,所以更推荐方案1,让布局系统正常工作。
内容的提问来源于stack exchange,提问作者Josef K.
相关产品推荐
相关产品推荐

