From e903c01b4e24c51598cd7b56e143e6dedd7454f6 Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 6 Mar 2020 13:37:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/ui/widget/ScrollTextView.java | 103 ------------------ .../io/legado/app/ui/widget/ScrollTextView.kt | 81 ++++++++++++++ 2 files changed, 81 insertions(+), 103 deletions(-) delete mode 100644 app/src/main/java/io/legado/app/ui/widget/ScrollTextView.java create mode 100644 app/src/main/java/io/legado/app/ui/widget/ScrollTextView.kt diff --git a/app/src/main/java/io/legado/app/ui/widget/ScrollTextView.java b/app/src/main/java/io/legado/app/ui/widget/ScrollTextView.java deleted file mode 100644 index 7fc1b7a5b..000000000 --- a/app/src/main/java/io/legado/app/ui/widget/ScrollTextView.java +++ /dev/null @@ -1,103 +0,0 @@ -package io.legado.app.ui.widget; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.text.Layout; -import android.util.AttributeSet; -import android.view.MotionEvent; - -import androidx.appcompat.widget.AppCompatTextView; - -public class ScrollTextView extends AppCompatTextView { - - //滑动距离的最大边界 - private int mOffsetHeight; - - //是否到顶或者到底的标志 - private boolean mBottomFlag = false; - - - public ScrollTextView(Context context) { - super(context); - } - - public ScrollTextView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - initOffsetHeight(); - } - - @Override - protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { - super.onTextChanged(text, start, lengthBefore, lengthAfter); - initOffsetHeight(); - } - - private void initOffsetHeight() { - int paddingTop; - int paddingBottom; - int mHeight; - int mLayoutHeight; - - //获得内容面板 - Layout mLayout = getLayout(); - if (mLayout == null) return; - //获得内容面板的高度 - mLayoutHeight = mLayout.getHeight(); - //获取上内边距 - paddingTop = getTotalPaddingTop(); - //获取下内边距 - paddingBottom = getTotalPaddingBottom(); - - //获得控件的实际高度 - mHeight = getMeasuredHeight(); - - //计算滑动距离的边界 - mOffsetHeight = mLayoutHeight + paddingTop + paddingBottom - mHeight; - if (mOffsetHeight <= 0) { - scrollTo(0, 0); - } - } - - @Override - public boolean dispatchTouchEvent(MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_DOWN) { - //如果是新的按下事件,则对mBottomFlag重新初始化 - mBottomFlag = mOffsetHeight <= 0; - } - //如果已经不要这次事件,则传出取消的信号,这里的作用不大 - if (mBottomFlag) { - event.setAction(MotionEvent.ACTION_CANCEL); - } - return super.dispatchTouchEvent(event); - } - - @SuppressLint("ClickableViewAccessibility") - @Override - public boolean onTouchEvent(MotionEvent event) { - boolean result = super.onTouchEvent(event); - //如果是需要拦截,则再拦截,这个方法会在onScrollChanged方法之后再调用一次 - if (!mBottomFlag) - getParent().requestDisallowInterceptTouchEvent(true); - return result; - } - - @Override - protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) { - super.onScrollChanged(horiz, vert, oldHoriz, oldVert); - if (vert == mOffsetHeight || vert == 0) { - //这里触发父布局或祖父布局的滑动事件 - getParent().requestDisallowInterceptTouchEvent(false); - mBottomFlag = true; - } - } - -} diff --git a/app/src/main/java/io/legado/app/ui/widget/ScrollTextView.kt b/app/src/main/java/io/legado/app/ui/widget/ScrollTextView.kt new file mode 100644 index 000000000..29f1a9fb8 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/widget/ScrollTextView.kt @@ -0,0 +1,81 @@ +package io.legado.app.ui.widget + +import android.annotation.SuppressLint +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import androidx.appcompat.widget.AppCompatTextView + +class ScrollTextView(context: Context?, attrs: AttributeSet?) : AppCompatTextView(context, attrs) { + //滑动距离的最大边界 + private var mOffsetHeight = 0 + + //是否到顶或者到底的标志 + private var mBottomFlag = false + + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + initOffsetHeight() + } + + override fun onTextChanged( + text: CharSequence, + start: Int, + lengthBefore: Int, + lengthAfter: Int + ) { + super.onTextChanged(text, start, lengthBefore, lengthAfter) + initOffsetHeight() + } + + private fun initOffsetHeight() { + val mLayoutHeight: Int + + //获得内容面板 + val mLayout = layout ?: return + //获得内容面板的高度 + mLayoutHeight = mLayout.height + //获取上内边距 + val paddingTop: Int = totalPaddingTop + //获取下内边距 + val paddingBottom: Int = totalPaddingBottom + + //获得控件的实际高度 + val mHeight: Int = measuredHeight + + //计算滑动距离的边界 + mOffsetHeight = mLayoutHeight + paddingTop + paddingBottom - mHeight + if (mOffsetHeight <= 0) { + scrollTo(0, 0) + } + } + + override fun dispatchTouchEvent(event: MotionEvent): Boolean { + if (event.action == MotionEvent.ACTION_DOWN) { + //如果是新的按下事件,则对mBottomFlag重新初始化 + mBottomFlag = mOffsetHeight <= 0 + } + //如果已经不要这次事件,则传出取消的信号,这里的作用不大 + if (mBottomFlag) { + event.action = MotionEvent.ACTION_CANCEL + } + return super.dispatchTouchEvent(event) + } + + @SuppressLint("ClickableViewAccessibility") + override fun onTouchEvent(event: MotionEvent): Boolean { + val result = super.onTouchEvent(event) + //如果是需要拦截,则再拦截,这个方法会在onScrollChanged方法之后再调用一次 + if (!mBottomFlag) parent.requestDisallowInterceptTouchEvent(true) + return result + } + + override fun onScrollChanged(horiz: Int, vert: Int, oldHoriz: Int, oldVert: Int) { + super.onScrollChanged(horiz, vert, oldHoriz, oldVert) + if (vert == mOffsetHeight || vert == 0) { + //这里触发父布局或祖父布局的滑动事件 + parent.requestDisallowInterceptTouchEvent(false) + mBottomFlag = true + } + } +} \ No newline at end of file