为WebView增加词典功能
This commit is contained in:
@@ -1,17 +1,112 @@
|
|||||||
package io.legado.app.ui.rss.read
|
package io.legado.app.ui.rss.read
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import android.view.ActionMode
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import io.legado.app.R
|
||||||
|
import io.legado.app.ui.dict.DictDialog
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
class VisibleWebView(
|
class VisibleWebView(
|
||||||
context: Context,
|
context: Context,
|
||||||
attrs: AttributeSet? = null
|
attrs: AttributeSet? = null
|
||||||
) : WebView(context, attrs) {
|
) : WebView(context, attrs) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
settings.javaScriptEnabled = true
|
||||||
|
settings.domStorageEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
override fun onWindowVisibilityChanged(visibility: Int) {
|
override fun onWindowVisibilityChanged(visibility: Int) {
|
||||||
super.onWindowVisibilityChanged(View.VISIBLE)
|
super.onWindowVisibilityChanged(View.VISIBLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun startActionMode(callback: ActionMode.Callback?): ActionMode {
|
||||||
|
val wrappedCallback = createWrappedCallback(callback)
|
||||||
|
return super.startActionMode(wrappedCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun startActionMode(callback: ActionMode.Callback?, type: Int): ActionMode {
|
||||||
|
val wrappedCallback = createWrappedCallback(callback)
|
||||||
|
return super.startActionMode(wrappedCallback, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createWrappedCallback(original: ActionMode.Callback?): ActionMode.Callback {
|
||||||
|
return object : ActionMode.Callback {
|
||||||
|
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
|
val result = original?.onCreateActionMode(mode, menu) ?: false
|
||||||
|
menu.add(Menu.NONE, MENU_ID_DICT, 0, R.string.dict)
|
||||||
|
getSelectedText { /* 触发缓存*/ }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
|
updateDictMenuItem(menu)
|
||||||
|
return original?.onPrepareActionMode(mode, menu) ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||||
|
when (item.itemId) {
|
||||||
|
MENU_ID_DICT -> {
|
||||||
|
getSelectedText { selectedText ->
|
||||||
|
if (selectedText.isNotBlank()) {
|
||||||
|
showDictDialog(selectedText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mode.finish()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
return original?.onActionItemClicked(mode, item) ?: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyActionMode(mode: ActionMode) {
|
||||||
|
original?.onDestroyActionMode(mode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDictMenuItem(menu: Menu) {
|
||||||
|
val dictItem = menu.findItem(MENU_ID_DICT)
|
||||||
|
dictItem?.let { item ->
|
||||||
|
getSelectedText { selectedText ->
|
||||||
|
item.isEnabled = selectedText.isNotBlank()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSelectedText(callback: (String) -> Unit) {
|
||||||
|
evaluateJavascript("(function(){return window.getSelection().toString();})()") { result ->
|
||||||
|
val selectedText = result
|
||||||
|
?.removeSurrounding("\"")
|
||||||
|
?.replace("\\n", "\n")
|
||||||
|
?.replace("\\t", "\t")
|
||||||
|
?.replace("\\\"", "\"")
|
||||||
|
?: ""
|
||||||
|
callback(selectedText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showDictDialog(selectedText: String) {
|
||||||
|
val activity = context as? AppCompatActivity
|
||||||
|
activity?.let {
|
||||||
|
val dialog = DictDialog(selectedText)
|
||||||
|
it.supportFragmentManager.beginTransaction()
|
||||||
|
.add(dialog, "DictDialog")
|
||||||
|
.commitAllowingStateLoss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val MENU_ID_DICT = 1001
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user