完美解决EditText和ScrollView的滚动冲突(下)

 更新时间:2016年06月20日 10:31:52   作者:曾博文  
这篇文章再次为大家详细介绍了完美解决EditText和ScrollView滚动冲突的方法,感兴趣的小伙伴们可以参考一下

上篇文章完美解决EditText和ScrollView的滚动冲突(上)中提到咱们自己写了一个判断EditText是否可以在垂直方向上滚动的方法,那么这个方法是如何得来的呢?
其实Android API里是有一个判断控件是否可以在垂直方向上滚动的方法的,方法名字叫做canScrollVertically(int direction),代码如下:

/**
   * Check if this view can be scrolled vertically in a certain direction.
   *
   * @param direction Negative to check scrolling up, positive to check scrolling down.
   * @return true if this view can be scrolled in the specified direction, false otherwise.
   */
  public boolean canScrollVertically(int direction) {
    final int offset = computeVerticalScrollOffset();
    final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
    if (range == 0) return false;
    if (direction < 0) {
      return offset > 0;
    } else {
      return offset < range - 1;
    }
  }

根据注释不难得知此方法是用来判断当前控件是否可以在垂直的方向上进行滚动的:当参数direction传的是负值的时候,会判断当前控件是否可以向上滚动;否则当参数direction传的是非负值的时候,会判断当前控件是否可以向下滚动。
由此得知我们完全可以利用此方法这样来判断一个控件是否可以在垂直方向上进行滚动:

if(editText.canScrollVertically(-1) || editText.canScrollVertically(0)) {
      //垂直方向上可以滚动
    }

那么为什么不使用此方法呢?很无奈,因为这个方法是在API 14(也就是Android4.0)才提供的方法,而很多时候我们需要兼容4.0以下的手机,所以并不能直接使用。虽然不能直接使用此方法,不过我们可以看一下它内部是怎么实现的,直接抄过来不就得了!不过还有个悲剧的消息,computeVerticalScrollOffset()、computeVerticalScrollRange()和computeVerticalScrollExtent()这三个方法都是protected方法,所以我们仍然不能使用,没办法,我们只好一块儿将这三个方法内部的实现都看一下。

1.computeVerticalScrollOffset()方法

首先是computeVerticalScrollOffset()方法:`

protected int computeVerticalScrollOffset() {
    return mScrollY;
  }

此方法定义在View中,并且EditText和TextView都没有重写,所以其返回的必然是mScrollY。那么不适用这个方法我们该如何得到mScrollY呢?稍微猜测一下,既然有mScrollY这么一个变量,那么就应该有其的get方法。查看API,不难发现View中确实有个getScrollY()方法:

public final int getScrollY() {
    return mScrollY;
  }

2. computeVerticalScrollRange()方法

OK,第一个方法的值我们通过getScrollY()拿到了,接下来咱们来看第二个方法computeVerticalScrollRange():

protected int computeVerticalScrollRange() {
    return getHeight();
  }

在View中很快找到了此方法,但此方法使我们需要的吗?不要忘了我们使用的是EditText!所以我们需要查看一下在EditText和TextView中是否对此方法进行了重载。不出我们所料,这个方法还真在TextView中进行了重载:

@Override
  protected int computeVerticalScrollRange() {
    if (mLayout != null)
      return mLayout.getHeight();

    return super.computeVerticalScrollRange();
  }

这个方法返回的是mLayout的高度,那么我们怎么获得mLayout呢?刚刚咱们获得mScrollY时使用了getScrollY()方法,那么是不是会有一个getLayout()方法呢?抱着试试看的态度,忽然间发现在TextView中还真有这么一个方法:

public final Layout getLayout() {
    return mLayout;
  }

3.computeVerticalScrollExtent()方法

恩,第二个方法的值我们也通过getLayout().getHeight()方法拿到了,现在咱们就来看一下最后一个方法computeVerticalScrollExtent():

protected int computeVerticalScrollExtent() {
    return getHeight();
  }

在View中我们同样找到了此方法,但根据第二个方法的经验,我们还应该去EditText和TextView中看一下有没有重载。又一次地不出我们所料,这个方法果然在TextView中进行了重载:

@Override
  protected int computeVerticalScrollExtent() {
    return getHeight() - getCompoundPaddingTop() - getCompoundPaddingBottom();
  }

然后不难发现,此处使用的三个方法getHeight()、getCompoundPaddingTop()和getCompoundPaddingBottom()都是public方法,我们直接调用即可。
至此,我们已经可以完全对canScrollVertically(int direction)这个方法进行重写了,而重写之后的方法就是咱们上一篇文章中使用的canVerticalScroll(EditText editText)方法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • android使用flutter的ListView实现滚动列表的示例代码

    android使用flutter的ListView实现滚动列表的示例代码

    现如今打开一个 App,比如头条、微博,都会有长列表,那么android使用flutter的ListView滚动列表如何实现,本文就来详细的介绍一下,感兴趣的同学可以来了解一下
    2018-12-12
  • android使用DataBinding来设置空状态

    android使用DataBinding来设置空状态

    本篇文章主要介绍了android使用DataBinding来设置空状态,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • 安卓中出现过的一些容易被忽略的异常整理

    安卓中出现过的一些容易被忽略的异常整理

    今天小编就为大家分享一篇关于安卓中出现过的一些容易被忽略的异常整理,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • AndroidQ(10)分区存储完美适配方法

    AndroidQ(10)分区存储完美适配方法

    这篇文章主要介绍了AndroidQ(10)分区存储完美适配方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • Android Bluetooth蓝牙技术使用流程详解

    Android Bluetooth蓝牙技术使用流程详解

    这篇文章主要介绍了Android Bluetooth蓝牙技术使用流程详解的相关资料,需要的朋友可以参考下
    2016-02-02
  • Android后台启动Activity的实现示例

    Android后台启动Activity的实现示例

    这篇文章主要介绍了Android后台启动Activity的实现示例,帮助大家更好的理解和学习使用Android开发,感兴趣的朋友可以了解下
    2021-04-04
  • android几种不同对话框的实现方式

    android几种不同对话框的实现方式

    这篇文章介绍了android几种不同对话框的实现,主要包括:1、显示提示消息的对话框.2、简单列表项对话框。3、单选列表项对话框。4、多选列表对话框。5、自定义列表项对话框。6、自定义View的对话框,需要的朋友可以参考下
    2015-08-08
  • Android Flutter实现页面切换转场动画效果

    Android Flutter实现页面切换转场动画效果

    Hero组件非常适合从列表、概览页切换到详情页转场动画场合。本文将利用Hero组件制作一个简单的页面切换转场动画效果,感兴趣的可以了解一下
    2022-06-06
  • Android4.1中BinderService用法实例分析

    Android4.1中BinderService用法实例分析

    这篇文章主要介绍了Android4.1中BinderService用法,以实例形式分析了Android4.1新增BinderService类的功能、原理及使用技巧,具有一定参考借鉴价值
    2015-10-10
  • android中处理各种触摸事件的方法浅谈

    android中处理各种触摸事件的方法浅谈

    android中处理各种触摸事件的方法浅谈,需要的朋友可以参考一下
    2013-06-06

最新评论