在 NestedScrollView 内带有锚点的 Webview

Posted

技术标签:

【中文标题】在 NestedScrollView 内带有锚点的 Webview【英文标题】:Webview with anchors inside NestedScrollView 【发布时间】:2018-04-11 13:51:13 【问题描述】:

我有一个 NestedScrollView,里面有一个 WebView。 WebView 包含一个带有锚点的 html 文件,这些锚点链接到同一个文件但位置不同(想象一下“菜单”和“内容”容器。当您单击菜单项时,“内容”中的相应部分应出现在屏幕上) .

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:id="@+id/svNested"
    android:layout_
    tools:showIn="@layout/activity_single"
    android:background="@color/colorPrimary">

        <WebView
            android:id="@+id/webView"
            android:layout_
            android:layout_/>

</android.support.v4.widget.NestedScrollView>

加载数据:

webView?.loadDataWithBaseURL(null, htmlContent, "text/html", "UTF-8", null)

问题是这些锚点没有按预期工作。

【问题讨论】:

你找到解决方案了吗? 不,抱歉。但那是 3 年。以前。 【参考方案1】:

我通过在WebView 中使用javascript 计算它们的位置,然后通过调用自定义URL 以编程方式滚动NestedScrollView 并使用WebViewClient 捕获它来让锚点工作。以下是一些 sn-ps(我只垂直滚动,但您可以轻松地将其扩展为也可以水平滚动):

在您的 Activity 或 Fragment 中(引用 NestedScrollViewWebView):

webView.webViewClient = object : WebViewClient() 
        override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean 
            if(url.startsWith("scrollto")) 
                val offset = url.replace("scrollto://", "");
                val offsetInt = MapUtils.getDensityIndependentPixels(offset.toFloat(), requireContext()).toInt()
                (webView.parent as NestedScrollView).scrollTo(0, offsetInt)
               return true
            
            return false
        
    

//We need this, because the measured pixels in the WebView don't use density of the screen
fun getDensityIndependentPixels(pixels: Float, context: Context): Float 
    return TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        pixels,
        context.resources.displayMetrics
    )

然后在您的 Javascript(或 HTML 中的 &lt;script&gt;-Tag)中:

function getOffset(el) 
    const rect = el.getBoundingClientRect();
    return 
        top: rect.top + window.pageYOffset,
        left: rect.left + window.pageXOffset
    ;

                    
function makeItScroll(id) 
     var element = document.getElementById(id)
     var offsetTop = getOffset(element).top
     window.location = "scrollto://"+offsetTop

最后像这样在你的 HTML 中使用它:

div你想滚动到:&lt;div id="here"&gt;...&lt;/div&gt;

a 滚动到那里:&lt;a href="javascript:makeItScroll('here');"&gt;...&lt;/a&gt;

【讨论】:

以上是关于在 NestedScrollView 内带有锚点的 Webview的主要内容,如果未能解决你的问题,请参考以下文章

如果在 nestedScrollView 内,RecyclerView 不回收

HTML 语义 - 充当锚点的按钮

Android:TextInputLayout 不适合页面并阻止页面在 NestedScrollView 内滚动

gitlab的md文件内使用锚点

js 定位到某个锚点的方法

将 SVG 多边形链接到锚点