Android导航组件不断重新加载WebView

xin*_*aiz 5 java android webview kotlin android-architecture-navigation

今天,我WebViewFragment使用中遇到了问题Android Navigation Component。就我而言,在Fragment1下方有一个按钮WebView。用户需要向下滚动才能单击它。单击它后,将打开一个新的目的地(Fragment2)。然后,当用户返回时Fragment1WebView将重新加载,然后视口再次滚动到顶部。

太烦人了。用户可能向下滚动了几分钟,并且总是在返回后将其扔到最顶端。我可以以某种方式阻止它重新加载/滚动回到顶部吗?

示例代码可能就这么简单:

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()
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

如果WebView包含视频,则加载可能甚至需要5秒钟。这是可怕的经历。

我尝试添加标志以仅加载一次,但从以下位置WebView导航返回时为空Fragment2

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
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

请注意,在现实生活中,我使用ViewModels并观察来自rest api的数据,但问题仍然存在。

另外,我提供的示例代码是用Kotlin编写的,但是如果Java中有解决方案,那么也很感激。

WebView从嵌套目标位置导航回来时,是否可以不重新加载并重置滚动位置?

Moo*_*oom 7

这就是片段以其基本形式(导航组件所使用的形式)如何工作的方式

片段本身被保存,但是它们的视图被破坏了。

这是在您的情况下发生的情况:

  • 片段1已创建
  • 创建了片段1视图(其中包含web视图)
  • 点击按钮
  • 片段1视图被破坏
  • 片段2已创建
  • 片段2视图已创建
  • 返回点击
  • 重新创建片段1视图
  • 片段2视图被破坏
  • 片段2被毁

如果您不使用导航组件,则使用非骇客方式很容易解决。
您可以在FragmentTransaction而不是上简单地.hide()结合使用,并且片段视图不会被破坏。 .add().replace()

但是,看到使用导航组件时,您自己并没有在处理碎片事务。

一种解决方法是在此处发布:https
//stackoverflow.com/a/55039009/2877453

保存片段及其变量后,您可以将视图另存为片段中的变量。
然后,检查onCreateView,如果变量为null,则像往常一样将其膨胀,如果不为null,则返回保存的视图。


小智 2

在更改片段之前使用此代码:-

if (getVisibleFragment() instanceof Fragment1){
      // do nothing
}else{
      // replace fragment
}


    public Fragment getVisibleFragment(){
                FragmentManager fragmentManager = getSupportFragmentManager();
                List<Fragment> fragments = fragmentManager.getFragments();
                if(fragments != null){
                    for(Fragment fragment : fragments){
                        if(fragment != null && fragment.isVisible())
                            return fragment;
                    }
                }
                return null;
    }
Run Code Online (Sandbox Code Playgroud)