TextView处理滑动冲突复盘

平常在ViewGroup中放一个textView组件,无可避免会出现textView内容过多而需要解决滑动冲突的问题.

大多数的做法就是再嵌套一个ScrollView来处理滑动冲突,而之所以用ScrollView的考虑无非就是处理是否滑动到边界,这么想想感觉不值得!

网上有很多介绍如何让TextView加载多内容时可滑动的文章,但是很少有解决其滑动冲突的文章.

今天就不说怎么支持滑动了,因为只是加一句

textView.setMovementMethod(ScrollingMovementMethod.getInstance());

既然支持了滑动,想必肯定也能在其中发现一二吧,于是翻开这个ScrollingMovementMethod类来,一眼就发现了这个方法

    @Override
    protected boolean bottom(TextView widget, Spannable buffer) {
        return scrollBottom(widget, buffer);
    }

继续跟踪看一眼,在BaseMovementMethod中就会发现结果

    /**执行滚动到底部动作。滚动到文档底部
     * Performs a scroll to bottom action.
     * Scrolls to the bottom of the document.
     *
     * @param widget The text view.
     * @param buffer The text buffer.
     * @return True if the event was handled.
     * @hide
     */
    protected boolean scrollBottom(TextView widget, Spannable buffer) {
        final Layout layout = widget.getLayout();
        final int lineCount = layout.getLineCount();//文本有多少行
        if (getBottomLine(widget) <= lineCount - 1) {//还没有到底部,则滚动到底部
            Touch.scrollTo(widget, layout, widget.getScrollX(),
                    layout.getLineTop(lineCount) - getInnerHeight(widget));
            return true;
        }
        return false;
    }

这里我们只需要知道是否滚动到底部,所以只需要

getBottomLine(TextView widget)方法即可,但发现是private修饰,所以写一个子类继承一下,于是就有了

import android.text.Layout;
import android.text.method.MovementMethod;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView;

public class SimpleScrollingMoveMethod extends ScrollingMovementMethod {

    public boolean isBottom(TextView widget){
        final Layout layout = widget.getLayout();
        final int lineCount = layout.getLineCount();
        return getBottomLine(widget) >= lineCount - 1;
    }

    public boolean isTop(TextView widget){
        return getTopLine(widget) == 0;
    }

    private int getTopLine(TextView widget) {
        return widget.getLayout().getLineForVertical(widget.getScrollY());
    }

    private int getBottomLine(TextView widget) {
        return widget.getLayout().getLineForVertical(widget.getScrollY() + getInnerHeight(widget));
    }

    private int getInnerHeight(TextView widget) {
        return widget.getHeight() - widget.getTotalPaddingTop() - widget.getTotalPaddingBottom();
    }

    public static MovementMethod getInstance() {
        if (sInstance == null)
            sInstance = new SimpleScrollingMoveMethod();

        return sInstance;
    }

    private static SimpleScrollingMoveMethod sInstance;
}

现在已经知道了是否滑动到底部了,接下来就是解决滑动冲突的问题了.网上还是有很多文章讲这个的,就不多说,上一段代码好了

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;

public class ScrollTextView extends android.support.v7.widget.AppCompatTextView {

    public ScrollTextView(Context context) {
        super(context);
    }

    public ScrollTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setMovementMethod(SimpleScrollingMoveMethod.getInstance());
    }

    float mLastY;
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mLastY = event.getY();
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
                case MotionEvent.ACTION_MOVE:
                    float scrollY = event.getY() - mLastY;
                    SimpleScrollingMoveMethod movementMethod = (SimpleScrollingMoveMethod) getMovementMethod();
                    if (scrollY < 0 && movementMethod.isBottom(this)){
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }else if (scrollY > 0 && movementMethod.isTop(this)){
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }else {
                        getParent().requestDisallowInterceptTouchEvent(true);
                    }
                    break;
        }
        return super.dispatchTouchEvent(event);
    }

}

完整的调用流程截图走一下好了.

到此结束了,仅处理textView如何处理底部事件滑动冲突,至于滑动的其他处理就类似了!不过没有ScrollView丝滑,哈哈!
补充一下,ScrollView与TextView判断到底或者到顶的方式不一样,ScrollView是View高度判断,而TextView则是文字行数判断,所以还是ScrollView处理的精确一些

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值