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
    评论
如果你想让 TextView 支持滑动,可以将其放入一个 ScrollView 中。ScrollView 是一个可以垂直滚动的容器,它只能包含一个子元素。你可以将 TextView 放入 ScrollView 中,然后当 TextView 中的内容超出屏幕范围时,用户就可以通过滑动屏幕来查看所有内容。 以下是一个简单的示例: ```xml <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet massa euismod, aliquam diam eget, ultrices odio. Vivamus vel arcu et quam congue efficitur. Sed vel purus non risus scelerisque viverra. Nam consequat, elit eget feugiat ullamcorper, tortor odio bibendum sapien, eget pellentesque libero odio vel elit. Sed non magna augue. Fusce ut elit vel quam blandit maximus non vel justo. Nunc varius, est quis dapibus tempor, velit libero gravida lacus, vel blandit eros justo a enim. Proin vitae leo eu libero gravida vestibulum. Nam finibus, augue vel dignissim molestie, eros eros pharetra enim, ac auctor enim sapien vel nisl. Sed rutrum tellus a bibendum pretium. Sed ut risus non quam faucibus luctus. Donec vel felis ut libero fringilla tempus." /> </ScrollView> ``` 在这个示例中,TextView 中的内容超出了屏幕的高度,因此 ScrollView 提供了垂直滚动的功能,用户可以通过滑动屏幕来查看所有的文本内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值