当前位置: 首页 > 知识库问答 >
问题:

如何获得相对于当前文本视图开始位置的滚动位置偏移?

欧奇希
2023-03-14

我有一个包含文本视图的回收器视图。文本视图的数量可以变化,它们的大小也可以变化,并且可以动态更改。

当用户滚动到列表中的某个位置并退出应用程序时,我希望能够在下一个会话中返回到该确切位置。

为此,我需要知道从视图中当前TextView开始的地方已经滚动了多少像素,以及滚动的当前位置。例如,如果用户看到第三个TextView,并从该TextView开始的地方向下滚动100个像素,我将能够使用scrolltopositionwithcoffset(2,100)返回到这个点。如果文本视图改变了大小(由于字体改变),我也可以通过使用文本视图的高度计算偏移量的百分比来返回到同一个点。

问题是,我无法得到任何准确庄园的偏移值。

我知道我可以使用RecyclerView或Webview的get scroll Y对Y值进行运行计算,但这并没有给我TextView实际开始的位置。我可以听用户滚动超过任何TextView的开头并记录Y位置,但这在快速滚动时是不准确的。

有没有更好的方法?

共有2个答案

漆雕彦
2023-03-14

我通过转换为ListView解决了这个问题:

lateinit var adapterRead: AdapterRead // Custom Adapter
lateinit var itemListView: ListView

/*=======================================================================================================*/
// OnViewCreated

itemListView = view.findViewById(R.id.read_listview)
setListView(itemListView)

// Upon entering this Fragment, will automatically scroll to saved position:
itemListView.afterMeasured {
    scrollToPosition(itemListView, getPosition(), getOffset())
    }


itemListView.setOnScrollListener(object : AbsListView.OnScrollListener {
    private var currentFirstVisibleItem = 0
    var offset = 0
    override fun onScrollStateChanged(view: AbsListView, scrollState: Int) {
        // When scrolling stops, will save the current position and offset:
        if(scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
            offset = if(itemListView.getChildAt(0) == null) 0 else itemListView.getChildAt(0).top - itemListView.paddingTop
            saveReadPosition(getReadPosition(itemListView), offset)
        }
    }

    override fun onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int, totalItemCount: Int) {
        currentFirstVisibleItem = firstVisibleItem
    }
})

/*=======================================================================================================*/
// Thanks to https://antonioleiva.com/kotlin-ongloballayoutlistener/ for this:

inline fun <T : View> T.afterMeasured(crossinline f: T.() -> Unit) {
    viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            if(measuredWidth > 0 && measuredHeight > 0) {
                viewTreeObserver.removeOnGlobalLayoutListener(this)
                f()
            }
        }
    })
}
/*=======================================================================================================*/
fun setListView(lv: ListView) {
    adapterRead = AdapterRead(list, context!!)
    lv.apply {this.adapter = adapterRead}
}

/*=======================================================================================================*/
fun scrollToPosition(lv: ListView, position: Int, offset: Int) {
    lv.post { lv.setSelectionFromTop(position, offset) }
}
/*=======================================================================================================*/
fun saveReadPosition(position: Int, offset: Int) {
    // Persist your data to database here
}
/*=======================================================================================================*/
fun getPosition() {
    // Get your saved position here
}
    /*=======================================================================================================*/
fun getOffse() {
    // Get your saved offset here
}
陶烨赫
2023-03-14

不要使用像素位置,使用视图的索引。使用布局管理器的findFirstVisibleItemPositionfindFirstCompletelyVisibleTItemPosition

这是一个非常流行的问题,尽管思考和搜索像素而不是索引可能是直观的。

在RecyclerView中获取可见项目

查找回收器视图中的第一个可见项是否为列表中的第一项

如何在回收器视图中获取当前可见项

不信任像素的一个很好的理由是,在索引不可用的某些情况下,例如旋转屏幕、调整/拆分应用程序大小以适应并排的其他应用程序、可折叠手机以及更改文本/屏幕分辨率,像素没有用。

 类似资料:
  • 我是新的android,我想显示我当前的位置像“巴基斯坦拉合尔乔哈尔镇”。有什么需要帮忙的吗?

  • 本文向大家介绍vim 相对于光标位置滚动,包括了vim 相对于光标位置滚动的使用技巧和注意事项,需要的朋友参考一下 示例 命令 描述 z 在窗口顶部重新绘制当前行,然后将光标放在该行的第一个非空白字符上。 zt 喜欢z但将光标留在同一列中。 z. 在窗口中心重绘当前行,然后将光标放在该行的第一个非空白字符上。 zz 喜欢z.但将光标留在同一列中。 z- 在窗口底部重画当前行,然后将光标放在该行的第

  • 当我需要配置滚动条默认滚动的位置的时候我该怎么做?有时我希望滚动条的起点和终点是我所指定的,而并非一个默认范围。

  • 问题内容: 是否可以获取当前滚动位置或React Native中组件的当前页面? 所以像这样: 问题答案: 尝试。 然后:

  • 问题内容: 我在另一个div内有两个div,我想使用css将一个子div放在父div的右上角,另一个子div放在父div的底下。即,我想对两个子div使用绝对定位,但是将它们相对于父div而不是页面定位。我怎样才能做到这一点? 范例html: 问题答案: 这工作,因为手段类似“使用,,,来定位自己相对于谁拥有最近的祖先或”。 因此,我们使have 和子代都有,然后使用和定位子代。

  • 在我的一个活动中有一个父容器,它调用由一个水平scrollview组成的子容器作为对象之一。有点像recyclerview,其中放置了行对象,有一个由水平滚动视图组成的公共行/项布局。 我的目标是同步horizontalscrollview的位置,这样,当我在其中一个对象上从位置1水平滚动到位置2时,包含HorizonalScrollview的所有其他项目都会从位置1更新到位置2。 这是我的主容器