我正在处理 安卓库将图像显示为固定的背景图像。为此,我每 10 毫秒根据 locationOnScreen 动态调整图像的位置。我知道这是一个很棒的解决方案,但我来这里是为了改进它:)
问题在于 有一个小故障当父可 ScrollView 滚动太快并且图像在另一个 View 移动时跳转时。 (点击 gif 可查看完整演示)
因为它是一个库,我不想在集成库时增加复杂性,这意味着没有滚动监听器、主题或没有窗口覆盖等。
尝试的解决方案:
- 改变循环延迟
- 库不能使用窗口背景
- 无法访问 Activity 主题或类似内容
处理程序
override fun run() {
fixedBackgroundImageLayout.getLocationOnScreen(locationOnScreen)
fixedBackgroundImagePlugin.update(locationOnScreen)
handler.postDelayed(this, 10)
}
FixedBackgroundImagePlugin#update
override fun update(locationOnScreen: IntArray) {
if (backgroundImageFrameLayout == null) {
return
}
yPosition = parentLocationOnScreen[1] - locationOnScreen[1]
backgroundImageFrameLayout.top = 2 * yPosition - lastYPosition - 10
lastYPosition = yPosition
}
backgroundImageFrameLayout 将图像作为背景图像。
我还设置了 sample repository如果需要,可以帮助您挖掘。
我愿意接受任何建议/领导
最佳答案
更新:我之前发布的代码有一些交互问题,令人惊讶的是,这些问题使代码工作但与 CPU Hook 。下面的代码与前面的代码基本相似,但行为不同。尽管新代码涉及一个滚动监听器,它会导致 View 重绘自身,但它是自包含的。需要滚动监听器来检测 View 何时在屏幕上重新定位。调用时,滚动监听器只会使 View 无效。
您可以在自定义 View BackgroundImageFrameLayout 中做所有您需要的事情。这是 draw()
覆盖将负责绘制保存图像的 FrameLayout 的背景。
将以下内容添加到 init block 中:
viewTreeObserver.addOnScrollChangedListener {
invalidate()
}
将以下覆盖方法添加到 BackgroundImageFrameLayout:override fun onDraw(canvas: Canvas) { // draw(canvas) may be better choice.
if (background == null) {
return
}
// Get the location of this view on the screen to compute its top and bottom coordinates.
val location = IntArray(2)
getLocationOnScreen(location)
val imageTop = location[1]
val imageBottom = imageTop + height
// Draw the slice of the image that should be viewable.
canvas.save()
canvas.translate(0f, -imageTop.toFloat())
background?.setBounds(0, imageTop, width, imageBottom)
background?.draw(canvas)
canvas.restore()
}
删除所有试图操纵背景的东西——你不需要它。这是带有新
onDraw()
的应用程序演示:我认为屏幕尺寸与图像尺寸之间可能存在其他一些问题,但这是你应该去的方向(恕我直言。)
关于android - 修复了没有滚动监听器的android中的背景图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57907618/