今天,在WebView
内使用Fragment
的{{1}}遇到了问题。
在我的情况下,Android Navigation Component
在Fragment1
下有一个按钮。用户需要向下滚动才能单击它。单击它后,将打开一个新的目的地(WebView
)。然后,当用户返回到Fragment2
时,Fragment1
被重新加载,并且视口再次滚动到顶部。
这很烦人。用户可能向下滚动了几分钟,并且总是在返回后将其扔到最顶端。我能以某种方式阻止它重新加载/滚动回到顶部吗?
示例代码可能就这么简单:
WebView
如果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()
}
}
}
包含视频,则加载可能最多需要5秒钟。这是糟糕的经历。
我尝试添加标志以仅加载一次,但是从WebView
导航回来时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
}
}
}
并观察来自rest api的数据,但是问题仍然存在。
此外,我提供的示例代码是用Kotlin编写的,但是如果有Java解决方案,那么也很感激。
从嵌套目标位置导航回来时是否可以不重新加载ViewModel
并重置滚动位置?
答案 0 :(得分:5)
这是片段以其基本形式(导航组件使用的形式)工作的方式
片段本身被保存,但是它们的视图被破坏了。
这是您所遇到的情况:
如果您不使用导航组件,则使用非骇客的方式很容易解决。
您可以在FragmentTransaction上简单地将.hide()
与.add()
结合使用,而不是.replace()
,并且片段视图不会被破坏。
但是看到您在使用导航组件时,您自己并没有在处理碎片事务。
一种解决方法是在此处发布:
https://stackoverflow.com/a/55039009/2877453
保存片段及其变量后,您可以将视图另存为片段中的变量。
然后检查onCreateView,如果变量为null,则像往常一样将其膨胀,如果不为null,则返回保存的视图。
答案 1 :(得分: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;
}
答案 2 :(得分:2)
请更改为此
class Fragment1 : Fragment() {
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
webView?.loadData(getString(R.string.some_very_long_html), "text/html", "UTF8")
}
}
尝试
答案 3 :(得分:2)
嘿,当您第一次遇到片段或返回其方法onViewCreated时,总是会一遍又一遍地调用,如果您想不想重置,可以通过一个全局布尔检查来完成,因为该全局变量片段恢复后将不会更改
赞
var shouldLoad = true
然后您想做什么
if(shouldLoad){
//do your work
//setting false to your boolean
shouldLoad = false
}else{
//if you need something else
}
答案 4 :(得分:2)
尝试一下-
这将在具有webview的片段中实现
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (view == null) {
// inflate your layout here
return view = inflater.inflate(R.layout.community_home_layout, container, false);
}else {
return view;
}