fix: magnifier правильные координаты + haptic при изменении выделения
Magnifier: - Конвертация overlay-local → view-local координаты для Magnifier.show() - Builder: 240×64px, cornerRadius 12, elevation 4, offset -80 (над текстом) Haptic: - TEXT_HANDLE_MOVE при каждом изменении selectionStart/selectionEnd - Как в Telegram: вибрация при перемещении handle по словам Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -127,7 +127,9 @@ class TextSelectionHelper {
|
||||
var newStart = charOffset.coerceIn(0, text.length)
|
||||
while (newStart > 0 && Character.isLetterOrDigit(text[newStart - 1])) newStart--
|
||||
if (newStart >= selectionEnd) return
|
||||
val changed = newStart != selectionStart
|
||||
selectionStart = newStart
|
||||
if (changed) hapticOnSelectionChange()
|
||||
}
|
||||
|
||||
fun updateSelectionEnd(charOffset: Int) {
|
||||
@@ -136,7 +138,16 @@ class TextSelectionHelper {
|
||||
var newEnd = charOffset.coerceIn(0, text.length)
|
||||
while (newEnd < text.length && Character.isLetterOrDigit(text[newEnd])) newEnd++
|
||||
if (newEnd <= selectionStart) return
|
||||
val changed = newEnd != selectionEnd
|
||||
selectionEnd = newEnd
|
||||
if (changed) hapticOnSelectionChange()
|
||||
}
|
||||
|
||||
private fun hapticOnSelectionChange() {
|
||||
magnifierView?.performHapticFeedback(
|
||||
HapticFeedbackConstants.TEXT_HANDLE_MOVE,
|
||||
HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING
|
||||
)
|
||||
}
|
||||
|
||||
fun beginHandleDrag(isStart: Boolean, touchX: Float, touchY: Float) {
|
||||
@@ -180,24 +191,30 @@ class TextSelectionHelper {
|
||||
magnifierView = view
|
||||
}
|
||||
|
||||
fun showMagnifier(x: Float, y: Float) {
|
||||
fun showMagnifier(overlayLocalX: Float, overlayLocalY: Float) {
|
||||
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.P) return
|
||||
val view = magnifierView ?: return
|
||||
if (!movingHandle) return
|
||||
if (magnifier == null) {
|
||||
magnifier = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
|
||||
android.widget.Magnifier.Builder(view)
|
||||
.setSize(200, 80)
|
||||
.setCornerRadius(16f)
|
||||
.setSize(240, 64)
|
||||
.setCornerRadius(12f)
|
||||
.setElevation(4f)
|
||||
.setDefaultSourceToMagnifierOffset(0, -80)
|
||||
.build()
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
android.widget.Magnifier(view)
|
||||
}
|
||||
}
|
||||
val info = layoutInfo ?: return
|
||||
val localX = (x - info.windowX).coerceIn(0f, view.width.toFloat())
|
||||
val localY = (y - info.windowY).coerceIn(0f, view.height.toFloat())
|
||||
magnifier?.show(localX, localY)
|
||||
// Convert overlay-local → view-local (magnifierView coords)
|
||||
val viewLoc = IntArray(2)
|
||||
view.getLocationInWindow(viewLoc)
|
||||
val sourceX = (overlayLocalX + overlayWindowX - viewLoc[0]).coerceIn(0f, view.width.toFloat())
|
||||
val sourceY = (overlayLocalY + overlayWindowY - viewLoc[1]).coerceIn(0f, view.height.toFloat())
|
||||
magnifier?.show(sourceX, sourceY)
|
||||
}
|
||||
|
||||
fun hideMagnifier() {
|
||||
|
||||
Reference in New Issue
Block a user