navigateUp() 和 navigate(action_id) 没有按预期工作
navigateUp() and navigate(action_id) not working as expected
使用导航框架,我从 Homefragment
导航到 WhsSearchWebDB
并返回到 Homefragment
。
当通过 navController.navigate(R.id.action_whsSearchWebDB_to_nav_home)
或 navController.navigateUp()
返回时,屏幕完全变白并且 toolbar
仅部分更新:片段的名称已正确设置,但导航按钮显示后退箭头而不是三栏主页图标。
当通过后退按钮返回时(navController.navigate(R.id.action_whsSearchWebDB_to_nav_home)
和 navController.navigateUp()
评论,当然),一切正常。
我需要以编程方式返回,而不是通过用户单击后退按钮。我必须改变什么?
mobile_navigation.xml:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@id/nav_home">
<fragment
android:id="@+id/nav_home"
android:name="be.ema.golfclubdataconversion.ui.home.HomeFragment"
android:label="@string/menu_home"
tools:layout="@layout/fragment_home" >
<action
android:id="@+id/action_nav_home_to_whsSearchWebDB"
app:destination="@id/whsSearchWebDB" />
</fragment>
<fragment
android:id="@+id/nav_gallery"
android:name="be.ema.golfclubdataconversion.ui.gallery.GalleryFragment"
android:label="@string/menu_gallery"
tools:layout="@layout/fragment_gallery" />
<fragment
android:id="@+id/nav_slideshow"
android:name="be.ema.golfclubdataconversion.ui.slideshow.SlideshowFragment"
android:label="@string/menu_slideshow"
tools:layout="@layout/fragment_slideshow" />
<fragment
android:id="@+id/whsSearchWebDB"
android:name="be.ema.golfclubdataconversion.ui.WhsSearchWebDB"
android:label="WhsSearchWebDB"
tools:layout="@layout/search_web_db">
<action
android:id="@+id/action_whsSearchWebDB_to_nav_home"
app:destination="@id/nav_home" />
</fragment>
home_fragment代码:
public class HomeFragment extends Fragment {
public static View root = null;
private HomeViewModel homeViewModel;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
@Override
public void onViewCreated(View root, Bundle savedInstanceState) {
// super.onViewCreated(root, savedInstanceState);
// homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
Button openUrlBtn = root.findViewById(R.id.openUrlBtn);
openUrlBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavController navController = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
navController.navigate(R.id.action_nav_home_to_whsSearchWebDB);
}
});
}
}
WhsSearchWebDB 代码:
public class WhsSearchWebDB extends Fragment {
public static Activity activity;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.search_web_db, container, false);
return v;
}
@Override
public void onViewCreated(View root, Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState);
activity = getActivity();
String urlToBeOpened = "http://ncrdb.usga.org";
WebView webView = (WebView) root.findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url)
{
/* This call inject JavaScript into the page which just finished loading. */
webView.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
}
});
webView.loadUrl(urlToBeOpened);
}
public static class MyJavaScriptInterface {
@JavascriptInterface
public void processHTML(String html) {
NavController navController = Navigation.findNavController(activity, R.id.nav_host_fragment);
// navController.navigate(R.id.action_whsSearchWebDB_to_nav_home);
// if (!navController.navigateUp()) {
// System.out.println("nooooooo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
// }
}
}
}
**** 编辑 ****
这是预期的屏幕(在转到 WhsSearchWebDB
片段之前拍摄的照片:
这是尝试返回后的错误结果:
whsSearchWebDB 片段中的导航操作正在创建一个新片段,而不是弹出回原始片段。
<fragment
android:id="@+id/whsSearchWebDB"
android:name="be.ema.golfclubdataconversion.ui.WhsSearchWebDB"
android:label="WhsSearchWebDB"
tools:layout="@layout/search_web_db">
<action
android:id="@+id/action_whsSearchWebDB_to_nav_home"
// Change this
app:destination="@id/nav_home"
// To this to pop back
app:popUpTo="@id/nav_home" />
我没有包括 popUpToInclusive。
PopUPToInclusive 需要设置为 true,popUpTo 属性将从返回堆栈中删除所有目的地,包括给定目的地。
- 打开导航图
- Select动作,你要
- 在属性窗格中,将 homeFragment 的 popUptToInclusive 设置为 Select popUpToInclusive 复选框为真。
有关详细信息,请查看导航代码实验室。
https://developer.android.com/codelabs/android-navigation#6
我终于发现 processHTML
方法在后台线程上执行,因此不允许操作 UI 小部件。我更喜欢 crash/error 而不是我在问题中报告的意外行为。
我已通过实施 ViewModel
、选择 processHTML
方法和 观察[=20] 中的结果解决了这个问题=] 它在 UI 线程上如下:
@Override
public void onViewCreated(View root, Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState);
activity = getActivity();
String urlToBeOpened = "http://ncrdb.usga.org";
WebView webView = (WebView) root.findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url)
{
/* This call inject JavaScript into the page which just finished loading. */
webView.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
}
});
webView.loadUrl(urlToBeOpened);
TeeboxViewModel teeboxViewModel = new ViewModelProvider((ViewModelStoreOwner) activity).get(TeeboxViewModel.class);
teeboxViewModel.getSelected().observe(getViewLifecycleOwner(), item -> {
...
NavController navController = Navigation.findNavController(activity, R.id.nav_host_fragment);
navController.navigate(R.id.action_whsSearchWebDB_to_nav_newResult);
});
}
public static class MyJavaScriptInterface {
public static Map<String, String> coursesList = new HashMap<>();
@JavascriptInterface
public void processHTML(String html) {
...
TeeboxViewModel model = new ViewModelProvider((ViewModelStoreOwner) activity).get(TeeboxViewModel.class);
model.select(teeboxesList);
}
}
使用导航框架,我从 Homefragment
导航到 WhsSearchWebDB
并返回到 Homefragment
。
当通过 navController.navigate(R.id.action_whsSearchWebDB_to_nav_home)
或 navController.navigateUp()
返回时,屏幕完全变白并且 toolbar
仅部分更新:片段的名称已正确设置,但导航按钮显示后退箭头而不是三栏主页图标。
当通过后退按钮返回时(navController.navigate(R.id.action_whsSearchWebDB_to_nav_home)
和 navController.navigateUp()
评论,当然),一切正常。
我需要以编程方式返回,而不是通过用户单击后退按钮。我必须改变什么?
mobile_navigation.xml:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@id/nav_home">
<fragment
android:id="@+id/nav_home"
android:name="be.ema.golfclubdataconversion.ui.home.HomeFragment"
android:label="@string/menu_home"
tools:layout="@layout/fragment_home" >
<action
android:id="@+id/action_nav_home_to_whsSearchWebDB"
app:destination="@id/whsSearchWebDB" />
</fragment>
<fragment
android:id="@+id/nav_gallery"
android:name="be.ema.golfclubdataconversion.ui.gallery.GalleryFragment"
android:label="@string/menu_gallery"
tools:layout="@layout/fragment_gallery" />
<fragment
android:id="@+id/nav_slideshow"
android:name="be.ema.golfclubdataconversion.ui.slideshow.SlideshowFragment"
android:label="@string/menu_slideshow"
tools:layout="@layout/fragment_slideshow" />
<fragment
android:id="@+id/whsSearchWebDB"
android:name="be.ema.golfclubdataconversion.ui.WhsSearchWebDB"
android:label="WhsSearchWebDB"
tools:layout="@layout/search_web_db">
<action
android:id="@+id/action_whsSearchWebDB_to_nav_home"
app:destination="@id/nav_home" />
</fragment>
home_fragment代码:
public class HomeFragment extends Fragment {
public static View root = null;
private HomeViewModel homeViewModel;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
@Override
public void onViewCreated(View root, Bundle savedInstanceState) {
// super.onViewCreated(root, savedInstanceState);
// homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
Button openUrlBtn = root.findViewById(R.id.openUrlBtn);
openUrlBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavController navController = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
navController.navigate(R.id.action_nav_home_to_whsSearchWebDB);
}
});
}
}
WhsSearchWebDB 代码:
public class WhsSearchWebDB extends Fragment {
public static Activity activity;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.search_web_db, container, false);
return v;
}
@Override
public void onViewCreated(View root, Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState);
activity = getActivity();
String urlToBeOpened = "http://ncrdb.usga.org";
WebView webView = (WebView) root.findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url)
{
/* This call inject JavaScript into the page which just finished loading. */
webView.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
}
});
webView.loadUrl(urlToBeOpened);
}
public static class MyJavaScriptInterface {
@JavascriptInterface
public void processHTML(String html) {
NavController navController = Navigation.findNavController(activity, R.id.nav_host_fragment);
// navController.navigate(R.id.action_whsSearchWebDB_to_nav_home);
// if (!navController.navigateUp()) {
// System.out.println("nooooooo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
// }
}
}
}
**** 编辑 ****
这是预期的屏幕(在转到 WhsSearchWebDB
片段之前拍摄的照片:
这是尝试返回后的错误结果:
whsSearchWebDB 片段中的导航操作正在创建一个新片段,而不是弹出回原始片段。
<fragment
android:id="@+id/whsSearchWebDB"
android:name="be.ema.golfclubdataconversion.ui.WhsSearchWebDB"
android:label="WhsSearchWebDB"
tools:layout="@layout/search_web_db">
<action
android:id="@+id/action_whsSearchWebDB_to_nav_home"
// Change this
app:destination="@id/nav_home"
// To this to pop back
app:popUpTo="@id/nav_home" />
我没有包括 popUpToInclusive。 PopUPToInclusive 需要设置为 true,popUpTo 属性将从返回堆栈中删除所有目的地,包括给定目的地。
- 打开导航图
- Select动作,你要
- 在属性窗格中,将 homeFragment 的 popUptToInclusive 设置为 Select popUpToInclusive 复选框为真。
有关详细信息,请查看导航代码实验室。 https://developer.android.com/codelabs/android-navigation#6
我终于发现 processHTML
方法在后台线程上执行,因此不允许操作 UI 小部件。我更喜欢 crash/error 而不是我在问题中报告的意外行为。
我已通过实施 ViewModel
、选择 processHTML
方法和 观察[=20] 中的结果解决了这个问题=] 它在 UI 线程上如下:
@Override
public void onViewCreated(View root, Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState);
activity = getActivity();
String urlToBeOpened = "http://ncrdb.usga.org";
WebView webView = (WebView) root.findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url)
{
/* This call inject JavaScript into the page which just finished loading. */
webView.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
}
});
webView.loadUrl(urlToBeOpened);
TeeboxViewModel teeboxViewModel = new ViewModelProvider((ViewModelStoreOwner) activity).get(TeeboxViewModel.class);
teeboxViewModel.getSelected().observe(getViewLifecycleOwner(), item -> {
...
NavController navController = Navigation.findNavController(activity, R.id.nav_host_fragment);
navController.navigate(R.id.action_whsSearchWebDB_to_nav_newResult);
});
}
public static class MyJavaScriptInterface {
public static Map<String, String> coursesList = new HashMap<>();
@JavascriptInterface
public void processHTML(String html) {
...
TeeboxViewModel model = new ViewModelProvider((ViewModelStoreOwner) activity).get(TeeboxViewModel.class);
model.select(teeboxesList);
}
}