版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gaolh89/article/details/81304808
在《Android编程权威指南》(第3版) 第30章《 网页浏览》30.7 深度学习中,webview多层使用时,按返回键返回上一次网页的问题.
书中只是简单的描述了一下需要重写 Activity.onBackPressed() 方法,但没深入谈论.
一.之前只在Activity中重写过onBackPressed()
之前使用webview时,都是在Activity中,直接重写onBackPressed()方法.本以为fragment中也可以重写改方法,但结果发现并没有此方法.
因为mWebView 控件在Fragment中,不可能将控件传给宿主Activity.然后想着在Fragment定义一个方法,返回 WebView,然后在宿主的 onBackPressed()中 使用这个方法.
代码如下:(Fragment.class)
public WebView goBack() {
return mWebView;
}
在宿主Activity.class中
@Override
public void onBackPressed() {
WebView webView = PhotoGalleryFragment.newInstance().goBack();
if (webView.canGoBack()){
webView.goBack();
}else {
super.onBackPressed();
}
}
结果直接在Activity中报webview的空指针了.
二.解决方案
(一) 网上的方案:
看过这种方案,是可行的.但是,存在以下几个问题:
1、只适用于一个Activity上只有一个Fragment的情况。
2、只适用于没有Fragment嵌套的情况。
(二)优化
1.同样的先定义一个FragmentBackHandler 接口。
public interface FragmentBackHandler {
boolean onBackPressed();
}
2.定义一个BackHandlerHelper工具类,用于实现分发back事件,Fragment和Activity的外理逻辑是一样,所以两者都需要调用该类的方法。
public class BackHandlerHelper {
/**
* 将back事件分发给 FragmentManager 中管理的子Fragment,如果该 FragmentManager 中的所有Fragment都 * 没有处理back事件,则尝试
* FragmentManager.popBackStack() * * @return 如果处理了back键则返回 <b>true</b> * @see #handleBackPress
* (Fragment) * @see #handleBackPress(FragmentActivity)
*/
public static boolean handleBackPress(FragmentManager fragmentManager) {
List<Fragment> fragments = fragmentManager.getFragments();
if (fragments == null) {
return false;
}
for (int i = fragments.size() - 1; i >= 0; i--) {
Fragment child = fragments.get(i);
if (isFragmentBackHandled(child)) {
return true;
}
}
if (fragmentManager.getBackStackEntryCount() > 0) {
fragmentManager.popBackStack();
return true;
}
return false;
}
public static boolean handleBackPress(Fragment fragment) {
return handleBackPress(fragment.getChildFragmentManager());
}
public static boolean handleBackPress(FragmentActivity fragmentActivity) {
return handleBackPress(fragmentActivity.getSupportFragmentManager());
}
/**
* 判断Fragment是否处理了Back键 * * @return 如果处理了back键则返回 <b>true</b>
*/
public static boolean isFragmentBackHandled(Fragment fragment) {
return fragment != null && fragment.isVisible() && fragment.getUserVisibleHint()
//for ViewPager
&& fragment instanceof FragmentBackHandler && ((FragmentBackHandler)
fragment).onBackPressed();
}
}
3.当然 Fragment 也要实现 FragmentBackHandler接口(按需)
public class PhotoGalleryFragment extends Fragment implements FragmentBackHandler {
// .... 其他业务代码
// 重写onBackPressed()方法
@Override
public boolean onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
return true;
} else {
return false;
}
}
4.宿主Activity覆盖onBackPressed方法(必须)
@Override
public void onBackPressed() {
if (!BackHandlerHelper.handleBackPress(this)) {
super.onBackPressed();
}
}