今天我在使用 Android Navigation Component
的 Fragment
中遇到了 WebView
的问题。
在我的例子中,在 Fragment1
中有 WebView
下的按钮。用户需要向下滚动才能单击它。单击它后,将打开一个新的目的地(Fragment2
)。然后,当用户返回 Fragment1
时,WebView
被重新加载,并且视口(viewport)再次滚动到顶部。
这非常烦人。用户可能向下滚动了几分钟,并且在返回后总是将他抛到最顶部。我可以以某种方式阻止它重新加载/滚动回顶部吗?
示例代码可以这么简单:
class Fragment1 : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
webView.loadData(getString(R.string.some_very_long_html), "text/html", "UTF-8")
buttonBelowWebView.setOnClickListener {
navigateToFragment2()
}
}
}
如果 WebView
包含视频,加载可能需要长达 5 秒。这是一次糟糕的经历。
我尝试添加标志以仅加载一次,但是从 Fragment2
导航返回时 WebView
为空:
class Fragment1 : Fragment() {
var loaded = false
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if(!loaded) {
webView.loadData(getString(R.string.some_very_long_html), "text/html", "UTF-8")
loaded = true
}
}
}
请注意,在现实生活中我使用 ViewModel
s 并观察来自 rest api 的数据,但问题保持不变。
另外,我提供的示例代码是用 Kotlin 编写的,但如果有 Java 解决方案,那么也很感激。
从嵌套目的地导航回来时,是否可以不重新加载 WebView
并重置滚动位置?
最佳答案
这就是 fragment 在其基本形式中的工作方式(导航组件使用的)
fragment 本身被保存,但它们的 View 被破坏。
这就是您的场景中发生的情况:
- 已创建 fragment 1
- 已创建 fragment 1 View (其中包含 web View )
- 点击按钮
- fragment 1 View 被破坏
- 已创建 fragment 2
- 已创建 fragment 2 View
- 点击后退
- 重新创建 fragment 1 View
- fragment 2 View 被破坏
- fragment 2 被破坏
如果您不使用导航组件,那么使用非 hacky 的方式很容易解决这个问题。
您可以简单地在 FragmentTransaction 上使用 .hide()
结合 .add()
而不是 .replace()
, fragment View 将不被破坏。
但是当您使用导航组件时,您并没有自己处理 fragment 事务。
这里发布的解决方法是:
https://stackoverflow.com/a/55039009/2877453
fragment 及其变量保存后,您可以将 View 保存为 fragment 中的变量。
然后检查onCreateView,如果变量为null,像往常一样膨胀它,如果不是null,则返回你保存的 View 。
关于java - Android导航组件不断重新加载WebView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56115479/