安卓开发--EditText和ScrollView滑动的冲突,以及EditText内容过多导致被软键盘顶上去距离

安卓开发笔记--Edittext和ScrollView嵌套 以及和软键盘距离随着内容变远以及输入内容过多不可滑动

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


1.Edittext设置触摸监听事件

    android:id="@+id/renwumiaoshu"
    android:gravity="top|left"
    android:layout_marginTop="5dp"
    android:hint="输入任务描述"
    android:textSize="15sp"
    android:background="@drawable/renwumiaoshu_bg"
    android:layout_gravity="center_horizontal"
    android:layout_width="340dp"
    android:layout_height="90dp" />

public class Activity_Deatail extends BaseToobarRightViewActivity implements View.OnTouchListener{
renwumiaoshu.setOnTouchListener(this);

@Override
public boolean onTouch(View view, MotionEvent event) {


    //触摸的是EditText并且当前EditText可以滚动则将事件交给EditText处理;否则将事件交由其父类处理
    if ((view.getId() == R.id.renwumiaoshu &&canVerticalScroll(renwumiaoshu))) {
        view.getParent().requestDisallowInterceptTouchEvent(true);
        if (event.getAction() == MotionEvent.ACTION_UP) {
            view.getParent().requestDisallowInterceptTouchEvent(false);
        }
    }
    return false;
}
2.先判断是否竖直可以滑动,再禁止分发触摸事件到父view 即ScrollView

/**
 * 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);
}

3.在清单文件AndroidManifest.xml 里对应的Activity里加入一行下面的代码

android:windowSoftInputMode="adjustPan"
/**
 "stateUnspecified" 软键盘的状态(是否它是隐藏或可见)没有被指定。系统将选择一个合适的状态或依赖于主题的设置。
 这个是为了软件盘行为默认的设置。

 "stateUnchanged" 软键盘被保持无论它上次是什么状态,是否可见或隐藏,当主窗口出现在前面时。

 "stateHidden" 当用户选择该Activity时,软键盘被隐藏——也就是,当用户确定导航到该Activity时,
 而不是返回到它由于离开另一个Activity
 "stateAlwaysHidden" 软键盘总是被隐藏的,当该Activity主窗口获取焦点时。

 "stateVisible" 软键盘是可见的,当那个是正常合适的时(当用户导航到Activity主窗口时)
 "stateAlwaysVisible" 当用户选择这个Activity时,软键盘是可见的——也就是,也就是,当用户确定导航到该Activity时,
 而不是返回到它由于离开另一个Activity
 "adjustUnspecified" 它不被指定是否该Activity主窗口调整大小以便留出软键盘的空间,
 或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何
 布局视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在
 一个较小的区域中可见的。这个是主窗口默认的行为设置。

 "adjustResize" Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间。

 "adjustPan" Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。
 相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。
 这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。 */
这样基本就解决了滑动和软键盘距离会越来越远的问题

  感谢 阅读 < ^ - ^ >


你可能感兴趣的:(Android)