限制源编辑框的最大行数,滚动到其他输入框更容易

This commit is contained in:
kunfei 2022-09-27 22:09:38 +08:00
parent aff0120775
commit a03298d805
2 changed files with 87 additions and 16 deletions

View File

@ -1,5 +1,6 @@
package io.legado.app.ui.widget.code
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
@ -12,6 +13,7 @@ import android.text.style.BackgroundColorSpan
import android.text.style.ForegroundColorSpan
import android.text.style.ReplacementSpan
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.annotation.ColorInt
import androidx.appcompat.widget.AppCompatMultiAutoCompleteTextView
import java.util.*
@ -37,6 +39,12 @@ class CodeView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
private val mSyntaxPatternMap: MutableMap<Pattern, Int> = HashMap()
private var mIndentCharacterList = mutableListOf('{', '+', '-', '*', '/', '=')
//滑动距离的最大边界
private var mOffsetHeight = 0
//是否到顶或者到底的标志
private var mBottomFlag = false
private val mUpdateRunnable = Runnable {
val source = text
highlightWithoutChange(source)
@ -102,6 +110,83 @@ class CodeView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
addTextChangedListener(mEditorTextWatcher)
}
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()
}
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_DOWN) {
//如果是新的按下事件则对mBottomFlag重新初始化
mBottomFlag = mOffsetHeight <= 0
}
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
}
}
override fun showDropDown() {
val screenPoint = IntArray(2)
getLocationOnScreen(screenPoint)
val displayFrame = Rect()
getWindowVisibleDisplayFrame(displayFrame)
val position = selectionStart
val layout = layout
val line = layout.getLineForOffset(position)
val verticalDistanceInDp = (750 + 140 * line) / displayDensity
dropDownVerticalOffset = verticalDistanceInDp.toInt()
val horizontalDistanceInDp = layout.getPrimaryHorizontal(position) / displayDensity
dropDownHorizontalOffset = horizontalDistanceInDp.toInt()
super.showDropDown()
}
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)
}
}
private fun autoIndent(
source: CharSequence,
dest: Spanned,
@ -365,21 +450,6 @@ class CodeView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
highlightWhileTextChanging = updateWhileTextChanging
}
override fun showDropDown() {
val screenPoint = IntArray(2)
getLocationOnScreen(screenPoint)
val displayFrame = Rect()
getWindowVisibleDisplayFrame(displayFrame)
val position = selectionStart
val layout = layout
val line = layout.getLineForOffset(position)
val verticalDistanceInDp = (750 + 140 * line) / displayDensity
dropDownVerticalOffset = verticalDistanceInDp.toInt()
val horizontalDistanceInDp = layout.getPrimaryHorizontal(position) / displayDensity
dropDownHorizontalOffset = horizontalDistanceInDp.toInt()
super.showDropDown()
}
private inner class TabWidthSpan : ReplacementSpan() {
override fun getSize(
paint: Paint,

View File

@ -9,6 +9,7 @@
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine" />
android:inputType="textMultiLine"
android:maxLines="12" />
</io.legado.app.ui.widget.text.TextInputLayout>