1.ScrollView 嵌套 ScrollView
1.1需求
ScrollView 嵌套 ScrollViewPro(如下自定义的类),scrollViewPro最大高度是170。
为了解决滑动冲突,需要拦截父容器的触摸事件。
/**
* ScrollView 嵌套 ScrollView
* 1.子ScrollView设置最大高度
* 2.子ScrollView拦截父空间的触摸事件
*/
public class ScrollViewPro extends ScrollView {
private int maxHeight = 170;//如果没有设置精确的高度,则最大高度为maxHeight
public ScrollViewPro(Context context) {
super(context);
}
public ScrollViewPro(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollViewPro(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode == MeasureSpec.EXACTLY){//如果设置了精确的高度,则使用设置的高度
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}else{
measureChildren(widthMeasureSpec,heightMeasureSpec);
View child = getChildAt(0);
int childHeight = child.getMeasuredHeight();
ViewGroup.MarginLayoutParams layoutParams = (MarginLayoutParams) child.getLayoutParams();
int childMarTop = layoutParams.topMargin;
int childMarBottom = layoutParams.bottomMargin;
if ((getPaddingTop() + getPaddingBottom() + childMarTop + childMarBottom + childHeight) > maxHeight)
heightSize = maxHeight;
super.onMeasure(widthMeasureSpec,MeasureSpec.makeMeasureSpec(heightSize,MeasureSpec.AT_MOST));
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean flag = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
flag = super.onInterceptTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
flag = true;
break;
}
return flag;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_MOVE:
getParent().requestDisallowInterceptTouchEvent(true);
break;
}
return super.onTouchEvent(ev);
}
}
2.ScrollView嵌套可以滚动的TextView
为了解决滑动冲突重写TextView
public class ScrollTextView extends TextView {
public Layout mLayout;
public int paddingTop;
public int paddingBottom;
public int mHeight;
public int mLayoutHeight;
public int canScrollHeight;
public int mVert;//可以上滑的高度。初始值为0。最大为canScrollHeight
public ScrollTextView(Context context) {
super(context);
}
public ScrollTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mLayout = getLayout();
mLayoutHeight = mLayout.getHeight();
paddingTop = getTotalPaddingTop();
paddingBottom = getTotalPaddingBottom();
mHeight = getHeight();
canScrollHeight = mLayoutHeight + paddingTop + paddingBottom - mHeight;
}
float lastY;
float currentY;
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
lastY = event.getY();
case MotionEvent.ACTION_MOVE:
currentY = event.getY();
float dy = currentY - lastY;
if (dy > 0){//手指向下滑动
if (mVert == 0){
getParent().requestDisallowInterceptTouchEvent(false);
}else if(mVert > 0){
getParent().requestDisallowInterceptTouchEvent(true);
}
}else if(dy < 0){
if (mVert == canScrollHeight){
getParent().requestDisallowInterceptTouchEvent(false);
}else if(mVert < canScrollHeight){
getParent().requestDisallowInterceptTouchEvent(true);
}
}
lastY = currentY;
break;
case MotionEvent.ACTION_UP:
break;
}
return result;
}
@Override
protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
mVert = vert;
}
}