zoukankan      html  css  js  c++  java
  • ScrollView嵌套EditText联带滑动的解决的方法

    本篇文章的相关内容需结合上文:从ScrollView嵌套EditText的滑动事件冲突分析触摸事件的分发机制以及TextView的简要实现和冲突的解决的方法


    在说完了怎样解决ScrollView嵌套EditText的滑动事件冲突之后。我们接下来说一下怎样实现它们两者之间的联带滑动。什么是联带滑动呢,就是当EditText滑动究竟部的时候,这时就应该让外部的ScrollView跟着滑动,好让它们之间完毕连贯的滑动事件,就是我们这篇文章的目的。详细效果就像以下这样:


    上图是一个GIF图片。所以有些卡顿的效果。实际上效果是很流畅的。那么实现这样的效果该怎么做呢?


    我们知道,子View能够依据requestDisallowInterceptTouchEvent方法来请求是否同意其祖父布局拦截本次的触摸事件。那么,我们就有了初步的解决的方法。就是,在须要的时候,不要让祖父布局拦截事件,在不须要的时候,让它们拦截,这时。事件就会被交给祖父布局来处理,并会让ScrollView滑动起来。


    上篇文章,我们已经对这一步做了主要的处理。假设你已经依照上文实现了的话,发现并没有依照想象中的那样实现本效果。那么是哪里出现了问题。是哪里还有问题吗?


    细心的同学能够发现,我们在onScrollChanged方法中对到达顶部和底部时做了处理,同意祖父布局对事件进行拦截。

    可是,假设做了调试的话。onScrollChanged方法调用之后onTouchEvent方法也调用了一次requestDisallowInterceptTouchEvent,并设置的參数还是true,也就是说,刚才在onScrollChanged方法中做的处理被取消了。

    所以。这时我们须要加个标志。用于帮助onTouchEvent方法中的requestDisallowInterceptTouchEvent方法进行合理的调用。


    So。我们的问题就攻克了。


    只是还须要一些兴许工作,就是在dispatchTouchEvent推断时候有新一轮的事件被传递过来,这时。我们还须要将这个标志又一次初始化一下。


    所有的实现代码例如以下:

    <span style="font-family:'Microsoft YaHei';font-size:14px;">package com.example.sahadev.gridlayout;
    
    import android.content.Context;
    import android.text.Layout;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.widget.EditText;
    
    /**
     * Created by Sahadev on 2016/4/20.
     */
    public class MyEditText extends EditText {
    
        //滑动距离的最大边界
        private int mOffsetHeight;
    
        //是否到顶或者究竟的标志
        private boolean mBottomFlag = false;
    
        public MyEditText(Context context) {
            super(context);
            init();
        }
    
        public MyEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            int paddingTop;
            int paddingBottom;
            int mHeight;
            int mLayoutHeight;
    
            //获得内容面板
            Layout mLayout = getLayout();
            //获得内容面板的高度
            mLayoutHeight = mLayout.getHeight();
            //获取上内边距
            paddingTop = getTotalPaddingTop();
            //获取下内边距
            paddingBottom = getTotalPaddingBottom();
    
            //获得控件的实际高度
            mHeight = getHeight();
    
            //计算滑动距离的边界
            mOffsetHeight = mLayoutHeight + paddingTop + paddingBottom - mHeight;
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN)
                //假设是新的按下事件。则对mBottomFlag又一次初始化
                mBottomFlag = false;
            //假设已经不要这次事件。则传出取消的信号,这里的作用不大
            if (mBottomFlag)
                event.setAction(MotionEvent.ACTION_CANCEL);
            return super.dispatchTouchEvent(event);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            boolean result = super.onTouchEvent(event);
            //假设是须要拦截,则再拦截,这种方法会在onScrollChanged方法之后再调用一次
            if (!mBottomFlag)
                getParent().requestDisallowInterceptTouchEvent(true);
            return result;
        }
    
        @Override
        protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
            super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
            if (vert == mOffsetHeight || vert == 0) {
                //这里触发父布局或祖父布局的滑动事件
                getParent().requestDisallowInterceptTouchEvent(false);
                mBottomFlag = true;
            }
        }
    
    
    }
    </span>

    代码,相比上篇文章进行了略微的改良。

    看起来更加明白。


    所以。上面就是我们经常看到的对不同View之间进行连贯性滑动的解决的方法。



    PS:对于这样的事件类的调试,假设身边没有源代码能够调试的话。那么打印日志是一个好的解决的方法。


    经过这两篇文章,相信你一定会触摸事件之间的关系有了更进一步的了解。

  • 相关阅读:
    Manjaro 安装 VMware Pro 15
    RAID-0-10 搭建和使用
    列表的切换按钮,是什么实现的?
    动态表单的设计
    如何修改自定义表单的名字,不适用diyname,直接使用id
    php关于批量替换的测试
    fastadmin删除控制器,删除菜单,提示not found
    fastadmin自定义表单,如何根据字段信息,创建表,而且,可以随时修改字段的顺序
    fastadmin如何获取新增后的id,这个可以使用模型的钩子函数。
    fastadmin如何在弹窗内跳转?以及如何在非弹窗页面,做tab选项卡
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7391996.html
Copyright © 2011-2022 走看看