ScrollView中嵌套EditText滑动问题
在EditText中设置了最大行数,但是内容超果了最大行数限制,这时EditText是可以滑动的。但是如果在EditText嵌套在ScrollView中时,会使EditText的滑动事件失效。
解决方法为:
_editText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// 解决scrollView中嵌套EditText导致不能上下滑动的问题
v.getParent().requestDisallowInterceptTouchEvent(true);
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
return false;
}
});
如果需要支持可编辑与不可以编辑两种状态,还可以增加下面判断:
if (可编辑) {
_editText.setFocusableInTouchMode(true);
_editText.setFocusable(true);
_editText.requestFocus();
} else {
_editText.setFocusable(false);
_editText.setFocusableInTouchMode(false);
}
如果限制了EditText的最大行数,但是显示时EditText的行数小于最大行数时,在EditText范围内拖动时不会触发scrollView的滑动事件的,导致整个页面的滑动效果有卡顿不流畅的感觉,因为在EditText的触摸事件中就拦截了上层控件的滑动事件,所以还需要判断EditText是否可以滑动来控制是否拦截上层控件的 滑动事件。
增加了判断EditText能否上下滑动判断,修改为:
_editText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// 解决scrollView中嵌套EditText导致不能上下滑动的问题
// 如果这个EditText在垂直方向上的向上向下方向能滑动的情况下阻止父层的View截获touch事件
if (_contentTV.canScrollVertically(1) || _contentTV.canScrollVertically(-1)){
v.getParent().requestDisallowInterceptTouchEvent(true);
}
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
return false;
}
});
方法EditText.canScrollVertically(direction)是判断EditText在垂直方向上能否滑动。参数direction > 0 判断能否向下滑动,< 0 判断能否向上滑动。增加了此判断后,如果EditText是不可以滑动的,scrollView能触发滑动事件。
根据这个判断还能延伸出更好的效果,就是当EditText可滑动,用户向上滑动到顶或者向下滑动到底时,因为这时EditText是获取了事件监听所以就算EditText滑动到顶或底时,scrollView也是不可以触发活动的。当修改为下面的判断时,当EditText滑动到顶或底时能顺利触发scrollView的滑动事件,使整个页面更加人性化,更加自然。
_contentTV.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: oldY = event.getY(); break; case MotionEvent.ACTION_MOVE: // 当EditText可以上下滑动时,拦截上层布局事件 if (_contentTV.canScrollVertically(1) && _contentTV.canScrollVertically(-1)){ v.getParent().requestDisallowInterceptTouchEvent(true); }else{ float Y = event.getY(); // 向下滑动 if (Y - oldY < 0){ // 如果EditText能向下滑动 if (_contentTV.canScrollVertically(1)){ v.getParent().requestDisallowInterceptTouchEvent(true); }else{ v.getParent().requestDisallowInterceptTouchEvent(false); } } // 向上滑动 if (Y - oldY > 0){ // 如果EditText能向上滑动 if (_contentTV.canScrollVertically(-1)){ v.getParent().requestDisallowInterceptTouchEvent(true); }else{ v.getParent().requestDisallowInterceptTouchEvent(false); } } } break; case MotionEvent.ACTION_UP: oldY = 0; v.getParent().requestDisallowInterceptTouchEvent(false); break; }}