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() {}@Overrideprotected 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;}@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN)//如果是新的按下事件,則對mBottomFlag重新初始化mBottomFlag = false;//如果已經不要這次事件,則傳出取消的信號,這里的作用不大if (mBottomFlag)event.setAction(MotionEvent.ACTION_CANCEL);return super.dispatchTouchEvent(event);}@Overridepublic boolean onTouchEvent(MotionEvent event) {boolean result = super.onTouchEvent(event);//如果是需要攔截,則再攔截,這個方法會在onScrollChanged方法之后再調用一次if (!mBottomFlag)getParent().requestDisallowInterceptTouchEvent(true);return result;}@Overrideprotected 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:對于這種事件類的調試,如果身邊沒有源碼可以調試的話,那么打印日志是一個好的解決辦法。
經過這兩篇文章,相信你一定會觸摸事件之間的關系有了更進一步的了解。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的ScrollView嵌套EditText联带滑动的解决办法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android官方开发文档Trainin
- 下一篇: Android官方开发文档Trainin