[优化] 优化震动效果,新增正文选取时震动开关
This commit is contained in:
@@ -251,6 +251,7 @@ object PreferKey {
|
||||
|
||||
const val showTip = "showTip"
|
||||
const val sliderVibrator = "sliderVibrator"
|
||||
const val selectVibrator = "selectVibrator"
|
||||
const val audioCacheCleanTime = "audioCacheCleanTime"
|
||||
const val audioPreDownloadNum = "audioPreDownloadNum"
|
||||
}
|
||||
|
||||
@@ -990,6 +990,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
appCtx.putPrefBoolean(PreferKey.sliderVibrator, value)
|
||||
}
|
||||
|
||||
var selectVibrator: Boolean
|
||||
get() = appCtx.getPrefBoolean(PreferKey.selectVibrator, false)
|
||||
set(value) {
|
||||
appCtx.putPrefBoolean(PreferKey.selectVibrator, value)
|
||||
}
|
||||
|
||||
val audioPreDownloadNum: Int
|
||||
get() = appCtx.getPrefInt(PreferKey.audioPreDownloadNum, 10)
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@ import android.graphics.drawable.TransitionDrawable
|
||||
import android.icu.text.SimpleDateFormat
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import androidx.activity.addCallback
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.core.graphics.scale
|
||||
import androidx.core.view.HapticFeedbackConstantsCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.transition.TransitionManager
|
||||
@@ -43,7 +43,6 @@ import io.legado.app.databinding.ActivityAudioPlayBinding
|
||||
import io.legado.app.help.book.isAudio
|
||||
import io.legado.app.help.book.removeType
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.lib.dialogs.alert
|
||||
import io.legado.app.model.AudioPlay
|
||||
import io.legado.app.model.BookCover
|
||||
import io.legado.app.service.AudioPlayService
|
||||
@@ -332,7 +331,7 @@ class AudioPlayActivity :
|
||||
|
||||
addOnSliderTouchListener(object : Slider.OnSliderTouchListener {
|
||||
override fun onStartTrackingTouch(slider: Slider) {
|
||||
slider.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||
slider.performHapticFeedback(HapticFeedbackConstantsCompat.VIRTUAL_KEY)
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(slider: Slider) {}
|
||||
@@ -358,7 +357,7 @@ class AudioPlayActivity :
|
||||
|
||||
addOnSliderTouchListener(object : Slider.OnSliderTouchListener {
|
||||
override fun onStartTrackingTouch(slider: Slider) {
|
||||
slider.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||
slider.performHapticFeedback(HapticFeedbackConstantsCompat.VIRTUAL_KEY)
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(slider: Slider) {}
|
||||
|
||||
@@ -5,11 +5,11 @@ import android.animation.ValueAnimator
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewConfiguration
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.core.view.HapticFeedbackConstantsCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.legado.app.utils.findCenterViewPosition
|
||||
@@ -255,7 +255,7 @@ class WebtoonRecyclerView @JvmOverloads constructor(
|
||||
|
||||
override fun onLongTapConfirmed(ev: MotionEvent) {
|
||||
if (longTapListener?.invoke(ev) == true) {
|
||||
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
|
||||
performHapticFeedback(HapticFeedbackConstantsCompat.LONG_PRESS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.view.LayoutInflater
|
||||
import android.view.animation.Animation
|
||||
import android.widget.FrameLayout
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.view.HapticFeedbackConstantsCompat
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import com.google.android.material.slider.Slider
|
||||
@@ -20,7 +21,6 @@ import io.legado.app.model.ReadBook
|
||||
import io.legado.app.model.ReadManga
|
||||
import io.legado.app.ui.browser.WebViewActivity
|
||||
import io.legado.app.utils.ConstraintModify
|
||||
import io.legado.app.utils.VibrationUtils
|
||||
import io.legado.app.utils.activity
|
||||
import io.legado.app.utils.applyNavigationBarPadding
|
||||
import io.legado.app.utils.gone
|
||||
@@ -242,16 +242,16 @@ class MangaMenu @JvmOverloads constructor(
|
||||
ReadManga.moveToPrevChapter(true)
|
||||
}
|
||||
|
||||
seekReadPage.addOnChangeListener { slider, value, fromUser ->
|
||||
seekReadPage.addOnChangeListener { _, value, fromUser ->
|
||||
if (fromUser) {
|
||||
VibrationUtils.vibrate(context, 12)
|
||||
HapticFeedbackConstantsCompat.TEXT_HANDLE_MOVE
|
||||
callBack.skipToPage(value.toInt() - 1)
|
||||
}
|
||||
}
|
||||
|
||||
seekReadPage.addOnSliderTouchListener(object : Slider.OnSliderTouchListener {
|
||||
override fun onStartTrackingTouch(slider: Slider) {
|
||||
VibrationUtils.vibrate(context, 16)
|
||||
HapticFeedbackConstantsCompat.TEXT_HANDLE_MOVE
|
||||
vwMenuBg.setOnClickListener(null)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import androidx.activity.addCallback
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.view.HapticFeedbackConstantsCompat
|
||||
import androidx.core.view.get
|
||||
import androidx.core.view.size
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
@@ -939,7 +940,8 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
textMenuPosition.x = x
|
||||
textMenuPosition.y = top
|
||||
|
||||
root.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
|
||||
if (AppConfig.selectVibrator)
|
||||
root.performHapticFeedback(HapticFeedbackConstantsCompat.TEXT_HANDLE_MOVE)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -949,8 +951,8 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
cursorRight.x = x
|
||||
cursorRight.y = y
|
||||
cursorRight.visible(true)
|
||||
|
||||
root.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
|
||||
if (AppConfig.selectVibrator)
|
||||
root.performHapticFeedback(HapticFeedbackConstantsCompat.TEXT_HANDLE_MOVE)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ import androidx.annotation.OptIn
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.view.HapticFeedbackConstantsCompat
|
||||
import androidx.core.view.doOnAttach
|
||||
import androidx.core.view.forEach
|
||||
import androidx.core.view.isGone
|
||||
@@ -42,7 +43,6 @@ import io.legado.app.model.ReadBook
|
||||
import io.legado.app.ui.browser.WebViewActivity
|
||||
import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
|
||||
import io.legado.app.utils.ConstraintModify
|
||||
import io.legado.app.utils.VibrationUtils
|
||||
import io.legado.app.utils.activity
|
||||
import io.legado.app.utils.applyNavigationBarPadding
|
||||
import io.legado.app.utils.dpToPx
|
||||
@@ -470,7 +470,7 @@ class ReadMenu @JvmOverloads constructor(
|
||||
if (AppConfig.progressBarBehavior == "page")
|
||||
ReadBook.skipToPage(value.toInt() - 1)
|
||||
if (AppConfig.sliderVibrator)
|
||||
VibrationUtils.vibrate(context, 10)
|
||||
HapticFeedbackConstantsCompat.TEXT_HANDLE_MOVE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package io.legado.app.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
import android.os.VibratorManager
|
||||
|
||||
object VibrationUtils {
|
||||
|
||||
/**
|
||||
* 触发单次震动
|
||||
* @param context 上下文
|
||||
* @param milliseconds 震动时长(毫秒)
|
||||
*/
|
||||
fun vibrate(context: Context, milliseconds: Long) {
|
||||
val vibrator = getVibrator(context)
|
||||
vibrator.vibrate(
|
||||
VibrationEffect.createOneShot(
|
||||
milliseconds,
|
||||
VibrationEffect.DEFAULT_AMPLITUDE
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发带模式的震动
|
||||
* @param context 上下文
|
||||
* @param pattern 震动模式数组(如 longArrayOf(0, 200, 100, 300))
|
||||
* @param repeat 重复次数(-1 为不重复)
|
||||
*/
|
||||
fun vibratePattern(context: Context, pattern: LongArray, repeat: Int = -1) {
|
||||
val vibrator = getVibrator(context)
|
||||
vibrator.vibrate(VibrationEffect.createWaveform(pattern, repeat))
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Vibrator 实例(兼容 Android 12+)
|
||||
*/
|
||||
private fun getVibrator(context: Context): Vibrator {
|
||||
return if (Build.VERSION.SDK_INT >= 31) {
|
||||
val vibratorManager =
|
||||
context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
|
||||
vibratorManager.defaultVibrator
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user