如何让协调器布局在scrollTo函数之后应用行为?

问题描述 投票:0回答:1

有一个

CoordinatorLayout
包含一个
AppBarLayout
和一个
NestedScrollView
,其中包含一个
TextView
TextView
有 Markdown 文本。我想滚动到锚点 (
#header
)。下面的代码按预期工作,但是调用
NestedScrollView.scrollTo
后,
CoordinatorLayout
不会触发滚动时隐藏
AppBarLayout
的行为。

需要做什么才能让

CoordinatorLayout
接收到代码触发的滚动事件?我尝试过使用
smoothScrollTo
scrollBy
,不起作用。当用户手动滚动时,
AppBarLayout
按预期隐藏。

fun scrollToAnchor(view: View, anchor: String) {
    val textView = view as TextView
    textView.setTextIsSelectable(false)
    val spanned = textView.text as Spanned
    val spans = spanned.getSpans(0, spanned.length, AnchorSpan::class.java)
    if (spans != null) {
        for (span in spans) {
            if (anchor == span.anchor) {
                val start = spanned.getSpanStart(span)
                val line = textView.layout.getLineForOffset(start)
                val top = textView.layout.getLineTop(line)

                val scrollToFunc = (view.parent as? NestedScrollView)?.let { it::scrollTo } ?: view::scrollTo
                scrollToFunc.invoke(0, top)
                break
            }
        }
    }
    textView.setTextIsSelectable(true)
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/doc_page_coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/doc_paga_top_app_bar"
            style="@style/Widget.Material3.Toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:elevation="0dp"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll|enterAlways|snap"
            app:menu="@menu/menu_only_close"
            app:title="@string/docs_title" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="?actionBarSize"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView
            android:id="@+id/markdown_root"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="@dimen/view_indent_horizontal"
            android:isScrollContainer="true"
            android:scrollbarThumbVertical="@android:color/transparent"
            android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
            android:textColor="?attr/colorOnBackground"
            android:textIsSelectable="true"
            tools:text="Lorem ipsum dolor sit amet" />

    </androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
android kotlin android-coordinatorlayout
1个回答
0
投票

当您以编程方式滚动 NestedScrollView 时,AppBarLayout 可能不会自动隐藏,因为 AppBarLayout 的滚动行为依赖于用户的滚动手势,而不是编程滚动。但是,当您以编程方式滚动时,您可以手动触发 AppBarLayout 的隐藏行为。

滚动后在 AppBarLayout 上使用 setExpanded(false, true) 。这将折叠应用程序栏并确保它在您滚动到指定标题时隐藏。 步骤:

  1. 给 app_bar 布局 id

  2. setExpanded(false, true)

    fun scrollToAnchor(view: View, anchor: String) {
     val textView = view as TextView
     textView.setTextIsSelectable(false)
     val spanned = textView.text as Spanned
     val spans = spanned.getSpans(0, spanned.length, 
          AnchorSpan::class.java)
          if (spans != null) {
          for (span in spans) {
           if (anchor == span.anchor) {
            val start = spanned.getSpanStart(span)
            val line = textView.layout.getLineForOffset(start)
            val top = textView.layout.getLineTop(line)
    
             val appBarLayout = findViewById<AppBarLayout>(R.id.app_bar_layout) 
             appBarLayout.setExpanded(false, true)
    
    
            val scrollToFunc = (view.parent as? NestedScrollView)?.let { it::scrollTo } ?: view::scrollTo
            scrollToFunc.invoke(0, top)
            break
        }
    }
    

    } textView.setTextIsSelectable(true) }

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.