前提:项目中有个这样的需求,EditText是固定高度,根布局用scrollView包裹着,输入文字超过输入框的高度,要求editText中的文字可以上下滚动。
这样就会造成scrollview和EditText的滚动冲突。
参考这篇博客,里边有源代码跟踪,有兴趣的同学可以看看这里写链接内容
我这只是记录一下解决方案的代码片段。
如何解决这个问题呢?
方法一:
焦点在EditText的时候就将事件交由EditText处理,否则将事件交由ScrollView处理。
这个方案可以解决滚动冲突,但是有缺陷。
例如:EditText的高度只能显示3行文字,那么你输入了10行文字,当滑动到最后一行文字时,此时我们在EditText区域进行滑动并且期望整个页面能够滚动,但由于我们将事件交给了EditText进行处理,所以页面并不能滚动。这种体验不是很好。
方法二:
当EditText需要滑动的时候,把事件交给EditText,其他时候都交给ScrollView来处理。那就对EditText进行监听,判断当前焦点在EditText区域内并且可以上下滑动。方法代码:
/**
* EditText竖直方向是否可以滚动
*
* @param editText 需要判断的EditText
* @return true:可以滚动 false:不可以滚动
*/
private boolean canVerticalScroll(TypefaceEditText editText) {
int scrollY = editText.getScrollY(); //滚动的距离
int scrollRange = editText.getLayout().getHeight(); //控件内容的总高度
int scrollExtent = editText.getHeight() - editText.getCompoundPaddingTop() - editText.getCompoundPaddingBottom(); //控件实际显示的高度
int scrollDifference = scrollRange - scrollExtent; //控件内容总高度与实际显示高度的差值
if (scrollDifference == 0) {
return false;
}
return (scrollY > 0) || (scrollY < scrollDifference - 1);
}
对editText设置个监听:
mEditText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
if ((view.getId() == R.id.xxEditeTextId && canVerticalScroll(mEditText))) {
view.getParent().requestDisallowInterceptTouchEvent(true);
if (event.getAction() == MotionEvent.ACTION_UP) {
view.getParent().requestDisallowInterceptTouchEvent(false);
}
}
return false;
}
});
其实这样的设计不是很好,我觉得最好的体验还是输入框会随着文字的行数增多而增加高度,简单明了,也少了这些繁琐的方法