解决EditText和ScrollView的滑动冲突

不累赘,直接上方案

这里还是说下我们主要用到的方法是ViewParent.requestDisallowInterceptTouchEvent

    /**
     * Called when a child does not want this parent and its ancestors to
     * intercept touch events with
     * {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}.
     *
     * <p>This parent should pass this call onto its parents. This parent must obey
     * this request for the duration of the touch (that is, only clear the flag
     * after this parent has received an up or a cancel.</p>
     * 
     * @param disallowIntercept True if the child does not want the parent to
     *            intercept touch events.
     */
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept);

什么意思呢?先提供三种翻译吧,看完有个大概的了解

百度翻译:

/**
*当子级不希望此父级及其祖先
*拦截触摸事件
*{@link ViewGroup#onInterceptTouchEvent(MotionEvent)}。
*<p>此父级应将此调用传递给其父级。这个家长必须服从
*此请求的持续时间为触摸(即,只清除标志
*在这个家长收到up或cancel后</p>
*@param disallowtercept如果孩子不想让父母
*拦截触摸事件。
*/

谷歌翻译:

/ **
*当孩子不希望这个父母及其祖先去世时调用
*拦截触摸事件
* {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}。
* <p>此父级应将此呼叫传递给其父级。 这位父母必须服从
*此请求在触摸期间(即,仅清除标志
 *在此父母收到补办或取消订单后。</ p>
* @param disallowIntercept如果孩子不希望父母去做,则为True
*拦截触摸事件。
 * /

有道翻译

/ * *
*当子程序不希望父程序和父程序被调用
用。拦截触摸事件
* {@link ViewGroup # onInterceptTouchEvent (MotionEvent)}。
这个父节点应该将这个调用传递给它的父节点。这个家长必须服从
*此请求的持续时间为触摸(即,只清除标志
*在父节点接收到up或cancel后。
* @param disallowIntercept为真,如果子线程不希望父线程为真
拦截触摸事件。
* /

我总结翻译一下:

当子类不想其父类和基类调用onInterceptTouchEvent 方法
这个父类应该传递到它的父类,这父类必须在触摸的这段时间里遵循这个请求
(即,在这个父类收到up或cancel之后,清除标记)

(这个请求指 父类不调用onInterceptTouchEvent方法)

方法一

自定义EditText ,然后重写onTouchEvent,然后正常使用即可

package com.mm.michat.collect.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.EditText;

/**
 * Created by cgg on 2020/7/17.
 * 用于解决嵌套Scrollview的时候由于多行而产生的滑动冲突问题
 */
public class EditTextWithScrollView extends EditText {

    public EditTextWithScrollView(Context context) {
        super(context);
    }

    public EditTextWithScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditTextWithScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            //通知父控件不要干扰
            getParent().requestDisallowInterceptTouchEvent(true);
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            //通知父控件不要干扰
            getParent().requestDisallowInterceptTouchEvent(true);
        } else if (event.getAction() == MotionEvent.ACTION_UP) {

        }
        return super.onTouchEvent(event);
    }
}

方法二

在代码里重写onTouch方法,然后添加了一个滑动判断

    editText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                //触摸的是EditText并且当前EditText可以滚动则将事件交给EditText处理;否则将事件交由其父类处理
                if ((view.getId() == R.id.et_title && canVerticalScroll(editText))) {
                    view.getParent().requestDisallowInterceptTouchEvent(true);
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        view.getParent().requestDisallowInterceptTouchEvent(false);
                    }
                }
                return false;
            }
        });

    private boolean canVerticalScroll(EditText 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);
    }

效果图:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值