自定义View实战之
自定义LinearLayout,该LinearLayout用于包EditText,解决EditText与ScrollView的滑动冲突
当EditText放在ScrollView里面,存在滑动冲突。
注:当EditText中内容的高度大于EditText的高度时,我们需要滑动EditText。
我们要解决掉这个滑动冲突,实现:
1、当EditText中的内容的高度超出EditText的高度时,我们在EditText的区域上滑动,可以滑动EditText的内容。
2、当EditText中的内容的高度不超出EditText的高度时,我们在EditText的区域上滑动,仍然滑动ScrollView。
解决思路:
在EditText外面包一层LinearLayout,这个LinearLayout是我们自定义的。代码如下:
public class ScrollViewInsideLinearLayout extends LinearLayout {
private ScrollView parentScrollView;
private EditText editText;
private int showLineMax = 0;
public void setParentScrollView(ScrollView parentScrollView) {
this.parentScrollView = parentScrollView;
}
public void setEditText(EditText editText) {
this.editText = editText;
ScrollViewInsideLinearLayout.LayoutParams lp = (LayoutParams) editText.getLayoutParams();
showLineMax = lp.height / editText.getLineHeight();
}
public ScrollViewInsideLinearLayout(Context context) {
super(context);
}
public ScrollViewInsideLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (parentScrollView == null) {
return super.onInterceptTouchEvent(ev);
} else {
if (ev.getAction() == MotionEvent.ACTION_DOWN && editText.getLineCount() >= showLineMax) {
//将父scrollView的滚动事件拦截
setParentScrollAble(false);
} else if (ev.getAction() == MotionEvent.ACTION_UP) {
//把滚动事件恢复给父scrollView
setParentScrollAble(true);
}
}
return super.onInterceptTouchEvent(ev);
}
/**
* 是否把滚动事件交给scrollView
* @param flag
*/
private void setParentScrollAble(boolean flag) {
parentScrollView.requestDisallowInterceptTouchEvent(!flag);
}
然后,在业务代码里,我们设置下:
scrollViewInsideLinearLayout.setParentScrollView(scrollView);
scrollViewInsideLinearLayout.setEditText(et_info);
这样子,就可以了。
这里我们主要就是重写onInterceptTouchEvent方法,以及使用到了requestDisallowInterceptTouchEvent方法。