完美解决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开发技巧之我的菜单我做主(自定义菜单)

    Android开发技巧之我的菜单我做主(自定义菜单)

    Android SDK本身提供了一种默认创建菜单的机制,虽然功能上还不错,但是界面的美观度不是很理想,本结介绍一种实现方法:就是通过onKeyDown事件方法和PopupWindow实现自定义的菜单,感兴趣的朋友可以了解下
    2013-01-01
  • 浅谈一下Android的Activity

    浅谈一下Android的Activity

    这篇文章主要介绍了浅谈一下Android的Activity,活动是所有安卓应用程序的门面,凡事你在应用中看到的东西,都是放到活动中的,需要的朋友可以参考下
    2023-04-04
  • Kotlin类型安全构建器的一次运用记录

    Kotlin类型安全构建器的一次运用记录

    这篇文章主要给大家介绍了关于Kotlin类型安全构建器的一次运用,文中通过示例代码介绍的非常详细,对大家学习或者使用Kotlin具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-06-06
  • Android中系统自带锁WalkLock与KeyguardLock用法实例详解

    Android中系统自带锁WalkLock与KeyguardLock用法实例详解

    这篇文章主要介绍了Android中系统自带锁WalkLock与KeyguardLock用法,结合实例形式较为详细的分析了WalkLock与KeyguardLock的功能、作用、使用方法与相关注意事项,需要的朋友可以参考下
    2016-01-01
  • Android studio 下的APK打包失败问题解决办法

    Android studio 下的APK打包失败问题解决办法

    这篇文章主要介绍了Android studio 下的APK打包失败问题解决办法的相关资料,需要的朋友可以参考下
    2017-05-05
  • Android实现带描边的圆角图片

    Android实现带描边的圆角图片

    这篇文章主要为大家详细介绍了Android实现带描边的圆角图片,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Android使用Room数据库解决本地持久化的操作

    Android使用Room数据库解决本地持久化的操作

    Room 是一个持久性库,属于 Android Jetpack 的一部分,Room 是 SQLite 数据库之上的一个抽象层,Room 并不直接使用 SQLite,而是负责简化数据库设置和配置以及与数据库交互方面的琐碎工作,本文介绍了Android使用Room数据库解决本地持久化的操作,需要的朋友可以参考下
    2024-09-09
  • Android 自定义View的构造函数详细介绍

    Android 自定义View的构造函数详细介绍

    这篇文章主要介绍了Android 自定义View的构造函数详细介绍的相关资料,这里对构造函数进行了对比按需使用,需要的朋友可以参考下
    2016-12-12
  • Android网格视图GridView的使用

    Android网格视图GridView的使用

    网格视图GridView的排列方式与矩阵类似,当屏幕上有很多元素(文字、图片或其他元素)需要按矩阵格式进行显示时,就可以使用GridView控件来实现
    2016-01-01
  • Android Flutter实现仿闲鱼动画效果

    Android Flutter实现仿闲鱼动画效果

    目前正在做的项目,为了增加用户的体验度,准备增加一些动画效果。本文将通过Android Flutter实现仿闲鱼动画效果,感兴趣的可以尝试一下
    2023-02-02

最新评论