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

在网上搜了一下EditText和ScrollView的滚动冲突,发现几乎所有的解决方案都是触摸EditText的时候就将事件交由EditText处理,否则才将事件交由ScrollView处理。这样确实初步解决了两者之间的滚动冲突,但并不是最好的解决方案。比如,EditText本来可以显示6行文本,但是目前只显示了5行文本,此时我们在EditText区域进行滑动并期望整个页面能够滚动,但由于我们将事件交给了EditText进行处理,所以页面并不能滚动,这样的体验是极差的。其实我们更希望当EditText出现滚动条的时才将滚动事件交由它本身处理,其他情况下应当让ScrollView来处理。那么该如何进行实现呢?接下来咱们就做一个小Demo来实现这种方案。

1.布局文件

首先编写布局文件,可以看出这是非常简单的一个布局:一个ScrollView包裹着一个垂直方向的LinearLayout,LinearLayout中有两个TextView和一个EditText,其中为了区分EditText的范围,给其设置了一个背景rectangle_shape。

<ScrollView
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent">

 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="vertical">

 <TextView
 android:layout_width="match_parent"
 android:layout_height="300dp"
 android:text="Hello World Begin!"/>

 <EditText
 android:id="@+id/edit_text"
 android:hint="EditText"
 android:layout_width="match_parent"
 android:layout_height="200dp"
 android:gravity="top"
 android:background="@drawable/rectangle_shape"/>

 <TextView
 android:layout_width="match_parent"
 android:layout_height="300dp"
 android:text="Hello World End!"/>
 </LinearLayout>

</ScrollView>

2.rectangle_shape

背景rectangle_shape的代码,更没有什么技术含量。。。。。。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
 <solid android:color="#ffffff"/>
 <stroke android:color="#cccccc"
 android:width="1dp"/>

</shape>

3.MainActivity中的代码

这里就是主要的代码逻辑了。先给EditText设置OnTouchListener,然后先在OnTouch方法中判断当前点击的区域是否为EditText,如果为EditText区域则再判断是否可以在垂直方向上进行滚动,如果可以滚动则将事件交由EditText处理,否则将事件交由ScrollView处理。
此处最重要的就是如何判断EditText区域在垂直方向上可以滚动,此处的代码已经封装成了一个方法,大家可以直接使用。那么为什么要这样判断呢?如果大家仍有兴趣,请继续阅读完美解决EditText和ScrollView的滚动冲突(下)。

public class MainActivity extends Activity implements View.OnTouchListener {

  private EditText mEditText;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mEditText = (EditText) findViewById(R.id.edit_text);
    mEditText.setOnTouchListener(this);
  }

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

  /**
   * EditText竖直方向是否可以滚动
   * @param editText 需要判断的EditText
   * @return true:可以滚动  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)

相关推荐

  • Android中ScrollView实现滑动距离监听器的方法

    前言 众所周知ScrollView是我们经常使用的一个UI控件,也许你在使用ScrollView的过程中会发现,当你想监听ScrollView滑动的距离时却没有合适的监听器!当然在API 23中有setOnScrollChangeListener(View.OnScrollChangeListener l)可以使用,但是并不兼容低版本的API.那怎么办呢?只好重写ScrollView来实现对滑动距离的监听了. 话不多说,直接上代码: public class MyScrollView exten

  • Android ScrollView取消惯性滚动的方法

    ScrollView中惯性滚动的效果,想让这个ScrollView慢一点滑动或者接近drag(拖拽)操作,就提出了添加阻尼的说法.只要重新fling方法即可,将velocity值极至缩小. 实例如下: public class CustomHorizontalScrollView extends HorizontalScrollView { private Context context; private ScrollViewListenner listenner; private Custom

  • Android中实现监听ScrollView滑动事件

    时候我们需要监听ScroView的滑动情况,比如滑动了多少距离,是否滑到布局的顶部或者底部.可惜的是SDK并没有相应的方法,不过倒是提供了一个 复制代码 代码如下: protected void onScrollChanged(int x, int y, int oldx, int oldy) 方法,显然这个方法是不能被外界调用的,因此就需要把它暴露出去,方便使用.解决方式就是写一个接口, 复制代码 代码如下: package com.example.demo1;    public inter

  • android TextView不用ScrollViewe也可以滚动的方法

    代码 复制代码 代码如下: TextView textview = (TextView) findViewById(R.id.text);            /**             *              * 只有调用了该方法,TextView才能不依赖于ScrollView而实现滚动的效果.             * 要在XML中设置TextView的textcolor,否则,当TextView被触摸时,会灰掉.             */ textview.setMov

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

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

  • Android开发控制ScrollView滑动速度的方法

    本文实例讲述了Android开发控制ScrollView滑动速度的方法.分享给大家供大家参考,具体如下: 前言 由于各个Android平板触摸屏的材质不一样,滑动效果会有一些区别,有的比较灵敏,有的比较迟钝,这里就遇到了要求控制滑动速度的需求... 正文 翻阅查找ScrollView的文档并搜索了一下没有发现直接设置的属性和方法,这里通过继承来达到这一目的. /** * 快/慢滑动ScrollView * @author 农民伯伯 * */ public class SlowScrollView

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

    在网上搜了一下EditText和ScrollView的滚动冲突,发现几乎所有的解决方案都是触摸EditText的时候就将事件交由EditText处理,否则才将事件交由ScrollView处理.这样确实初步解决了两者之间的滚动冲突,但并不是最好的解决方案.比如,EditText本来可以显示6行文本,但是目前只显示了5行文本,此时我们在EditText区域进行滑动并期望整个页面能够滚动,但由于我们将事件交给了EditText进行处理,所以页面并不能滚动,这样的体验是极差的.其实我们更希望当EditT

  • 微信小程序自定义弹窗滚动与页面滚动冲突的解决方法

    本文为大家分享了微信小程序自定义弹窗滚动与页面滚动冲突的解决方法,供大家参考,具体内容如下 先看效果是否是自己需要的 实现步骤: 1.整个布局用作为根节点包裹所有view,并动态绑定scroll-view的scroll-y属性 2.样式文件中设置Page的overflow-y属性值为hidden 3.样式文件中设置scroll-view的height属性值为100% 4.打开自定义弹窗的点击事件中,更改isScroll的值为false,关闭弹窗的点击事件中,更改isScroll的值为true J

  • 微信小程序完美解决scroll-view高度自适应问题的方法

    第一种情况,scroll-view占据整屏 scroll-view { height: 100vh; } 第二种情况,scroll-view自适应页面剩余高度 xml文件 <view class="box"> <view class="box-head"></view> <scroll-view class="box-scroll"></scroll-view> </view>

  • 完美解决jQuery符号$与其他javascript 库、框架冲突的问题

    目前有大量的 javascript 开发框架,其中有一部分使用 $ 作为调用符号,这可能导致相互之间的冲突,而 jQuery 为解决这个问题,可以在 jQuery 导入时放弃 $ 使用权,届时 $ 则由其它框架使用,这样可以避免相同名字的函数调用不再冲突. jQuery 使用 noConflict 方法来放弃 $ 调用时的命名,之后由 jQuery 代替 $ 进行编写. 例如:alert($('#message').val()); 必须修改为 alert(jQuery('#message').v

  • Android 中ScrollView与ListView冲突问题的解决办法

    Android 中ScrollView与ListView冲突问题的解决办法 自定义MyListView public class MyListView extends ListView { public MyListView(Context context) { super(context); // TODO Auto-generated constructor stub } public MyListView(Context context, AttributeSet attrs) { sup

  • Django与Vue语法的冲突问题完美解决方法

    当我们在django web框架中,使用vue的时候,会遇到语法冲突. 因为vue使用{{}},而django也使用{{}},因此会冲突. 解决办法1: 在django1.5以后,加入了标签: {% verbatim myblock %} {% endverbatim myblock %} 被此标签包裹的代码将不会被Django的模板引擎渲染. 因此,我们可以把带有{{ }} 的Vue代码放在 {% verbatim myblock %}标签中间,例如: <div id="app1&quo

  • 完美解决mui框架off-canvas侧滑超出部分隐藏无法滚动的问题

    mui框架中off-canvas侧滑的一个缺点就是无法出现滚动条,因为它主要用途是设置类似于qq界面的那种格局,所以才无法滚动.那么如何解决这个问题呢? 解决方法: 一.在内容容器加上id,然后通过JS控制 <div class="mui-content mui-scroll-wrapper" id="scr1"> JS部分 <script> mui('#scr1').scroll(); </script> 二.利用创建子页面的方

  • 完美解决android 项目jar包冲突的问题

    大家在做开发中竟然需要用到一些三方库 或者 需要集成三方的SDK开发包,尤其是项目特别庞大的时候,引用的三方的东西特别多,那么肯定会碰到一些jar包冲突的情况. 常见的情况有以下几种 1.项目自己引用jar包重复 2.项目中jar包和三方SDK 3.三方sdk之间都含有相同类 4.打包时候出现编译错误,出现冲突 1.项目自己引用jar包重复 com.android.dex.DexException: Multiple dex files define Landroid/support/v4/ac

  • 5种方法完美解决android软键盘挡住输入框方法详解

    在开发中,经常会遇到键盘挡住输入框的情况,比如登录界面或注册界面,弹出的软键盘把登录或注册按钮挡住了,用户必须把软键盘收起,才能点击相应按钮,这样的用户体验非常不好.像微信则直接把登录按钮做在输入框的上面,但有很多情况下,这经常满足不了需求.同时如果输入框特别多的情况下,点击输入时,当前输入框没被挡住,但是当前输入框下面的输入框却无法获取焦点,必须先把键盘收起,再去获取下面输入框焦点,这样用户体验也非常不好,那有什么办法呢?  系统的adjustResize和adjustPan有什么区别,他们使

随机推荐