【Android】ScrollView 嵌套 ScrollView ,嵌套滚动的TextView

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;
    }
}

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值