【问题标题】:Relative links not working after goBack was called调用 goBack 后相对链接不起作用
【发布时间】:2019-12-01 14:48:32
【问题描述】:

我创建了一个简单的应用来重现该问题。我有一个带有相对链接的 html 文件(带有# 符号)。我正在将文件加载到 Android 的 WebView 中。但我只能通过链接访问一次。返回后,当我单击链接时,什么也没有发生。

重现步骤:

  • 打开页面
  • 点击链接 2
  • 按设备上的返回按钮
  • 点击链接 2 - 没有任何反应

以下是来源:

常见问题.html

<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, target-densityDpi=medium-dpi">
        <title>Title</title>
    </head>
    <body>
        <h1>FAQ</h1>

        <ul>
            <li><a href="#Foo">Link 1</a></li>
            <li><a href="#Bar">Link 2</a></li>
        </ul>

        <h1><a name="Foo">Link 1 body</a></h1>

        <p>a very very very long text</p>

        <h1><a name="Bar">Link 2 body</a></h1>

    </body>
</html>

activity_webview.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/outer_background">

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

FaqActivity.kt

class FaqActivity : AppCompatActivity() {

    private lateinit var webView: WebView

    @SuppressLint("NewApi")
    override fun onCreate(args: Bundle?) {
        super.onCreate(args)
        setContentView(R.layout.activity_webview)
        if (supportActionBar != null) {
            supportActionBar!!.setDisplayHomeAsUpEnabled(true)
            supportActionBar!!.setTitle(R.string.preference_about_faq)
        }
        webView = findViewById(R.id.webView)

        val sb = StringBuilder()
        try {
            val inp = resources.openRawResource(R.raw.faq)
            parseStream(inp, sb)
        } catch (e: Resources.NotFoundException) {
        }

        webView.visibility = View.INVISIBLE
        webView.settings.cacheMode = WebSettings.LOAD_NO_CACHE
        webView.webViewClient = object : WebViewClient() {

            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                // removes white screen blinking in the night mode
                webView.visibility = View.VISIBLE
            }

            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
                return if (url.startsWith("http")) {
                    val uri = Uri.parse(url)
                    val intent = Intent(Intent.ACTION_VIEW, uri)
                    try {
                        startActivity(intent)
                    } catch (e: ActivityNotFoundException) {

                    }
                    true
                } else {
                    false
                }
            }
        }
        webView.loadDataWithBaseURL(null, sb.toString(), "text/html", "UTF-8", null)
    }

    private fun parseStream(inputStream: InputStream, builder: StringBuilder) {
        val NL = System.getProperty("line.separator")
        val scanner = Scanner(inputStream, "UTF-8")
        try {
            while (scanner.hasNextLine()) {
                builder.append(scanner.nextLine() + NL)
            }
        } finally {
            scanner.close()
        }
    }

    override fun onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            super.onBackPressed()
        }
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            // Respond to the action bar's Up/Home button
            android.R.id.home -> {
                super.onBackPressed()
                return true
            }
        }
        return super.onOptionsItemSelected(item)
    }
}

源是一个 Kotlin 文件,但我很确定它不会影响问题。

【问题讨论】:

    标签: android html hyperlink android-webview


    【解决方案1】:

    您可以在onBackPressed()函数中使用webView.pageUp(true),而不是webView.goBack(),这样当您点击设备上的返回按钮时,它会滚动到顶部。

    【讨论】:

    • 这并不能解决问题。相对链接可以在页面中间。
    • 好吧,接下来你定义scrollY,在onPageFinished()方法中赋值scrolledY = webView.scrollY。最后,使用webView.scrollY = scrolledY 而不是webView.goBack()。我试过了,它有效。
    • 好的。如果我们使用 Stack 来存储 Y 坐标(如果我们有多个链接转换),它就可以工作。但是我们能否解决问题的原因而不试图解决后果?
    【解决方案2】:

    这是来自ugurcmk answer 的经过调整和测试的代码。 我希望它会对某人有所帮助。

    class FaqActivity : AppCompatActivity() {
    
        private lateinit var webView: WebView
        private val navigationStack = Stack<Int>()
    
        @SuppressLint("NewApi")
        override fun onCreate(args: Bundle?) {
            super.onCreate(args)
            setContentView(R.layout.activity_webview)
            if (supportActionBar != null) {
                supportActionBar!!.setDisplayHomeAsUpEnabled(true)
                supportActionBar!!.setTitle(R.string.preference_about_faq)
            }
            webView = findViewById(R.id.webView)
    
            val sb = StringBuilder()
            try {
                val inp = resources.openRawResource(R.raw.faq)
                parseStream(inp, sb)
            } catch (e: Resources.NotFoundException) {
            }
    
            webView.visibility = View.INVISIBLE
            webView.settings.cacheMode = WebSettings.LOAD_NO_CACHE
            webView.webViewClient = object : WebViewClient() {
    
                override fun onPageFinished(view: WebView?, url: String?) {
                    super.onPageFinished(view, url)
                    navigationStack.push(webView.scrollY)
                    // removes white screen blinking in the night mode
                    webView.visibility = View.VISIBLE
                }
    
                override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
                    return if (url.startsWith("http")) {
                        val uri = Uri.parse(url)
                        val intent = Intent(Intent.ACTION_VIEW, uri)
                        try {
                            startActivity(intent)
                        } catch (e: ActivityNotFoundException) {
                        }
                        true
                    } else {
                        false
                    }
                }
            }
            webView.loadDataWithBaseURL(null, sb.toString(), "text/html", "UTF-8", null)
        }
    
        private fun parseStream(inputStream: InputStream, builder: StringBuilder) {
            val NL = System.getProperty("line.separator")
            val scanner = Scanner(inputStream, "UTF-8")
            try {
                while (scanner.hasNextLine()) {
                    builder.append(scanner.nextLine() + NL)
                }
            } finally {
                scanner.close()
            }
        }
    
        override fun onBackPressed() {
            // the first element stores the first non-link onPageFinished, ignore it
            if (navigationStack.size > 1) {
                webView.scrollY = navigationStack.pop()
            } else {
                super.onBackPressed()
            }
        }
    
        override fun onOptionsItemSelected(item: MenuItem): Boolean {
            when (item.itemId) {
                // Respond to the action bar's Up/Home button
                android.R.id.home -> {
                    super.onBackPressed()
                    return true
                }
            }
            return super.onOptionsItemSelected(item)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 2019-06-11
      相关资源
      最近更新 更多