Fragment内放置WebView,点击手机返回键,如果不做处理,会直接退出Activity,不能返回之前打开的网页。
首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPressed(),所有BackHandledFragment的子类在onBackPressed方法中处理各自对Back事件的消费逻辑。onBackPressed返回布尔值,宿主Activity将会根据该方法的返回值判断子Fragment是否有消费Back事件。此外,宿主FragmentActivity还会保持一份当前Fragment的引用,当用户按下Back键时,宿主Activity会判断当前Fragment是否需要消费该事件,如果没有Fragment消费才会自己消费。
public abstract class BackHandledFragment extends Fragment {
protected BackHandledInterface mBackHandledInterface;
/**
* 所有继承BackHandledFragment的子类都将在这个方法中实现物理Back键按下后的逻辑,
* FragmentActivity捕捉到物理返回键点击事件后会首先询问Fragment是否消费该事件
* 如果Fragment没有消费,FragmentActivity自己才会消费该事件
*/
public abstract boolean onBackPressed();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//判断宿主FragmentActivity是否已继承了BackHandledInterface接口
if (!(getActivity() instanceof BackHandledInterface)) {
throw new ClassCastException("Hosting Activity must implement BackHandledInterface");
} else {
this.mBackHandledInterface = (BackHandledInterface) getActivity();
}
}
@Override
public void onStart() {
super.onStart();
//告诉FragmentActivity,当前Fragment在栈顶
mBackHandledInterface.setSelectedFragment(this);
}
}
宿主FragmentActivity需要实现BackHandledIntegerface,子Fragment会通过该接口告诉宿主FragmentActivity自己是当前屏幕可见的Fragment。
public interface BackHandledInterface {
void setSelectedFragment(BackHandledFragment selectedFragment);
}
在Fragment的onCreate中会判断宿主FragmentActivity是否已继承了该接口。在Fragment的onStart()方法中就会调用该接口告诉宿主FragmentActivity自己是当前屏幕可见的Fragment。
宿主FragmentActivity就可以在onBackPressed()方法中对Back事件进行判断处理了。
package com.example.mydemo;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.widget.RadioGroup;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements BackHandledInterface {
private RadioGroup mRadioGroup;
private List<Fragment> mFragmentList;
private int position = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRadioGroup = (RadioGroup) findViewById(R.id.radiogroup);
mFragmentList = new ArrayList<>();
mFragmentList.add(new HomeFragment());
mFragmentList.add(new MineFragment());
mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.rb_home:
position = 0;
break;
case R.id.rb_mine:
position = 1;
break;
}
Fragment currentFragment = mFragmentList.get(position);
//切换fragment
switchFragmentByReplace(currentFragment);
}
});
mRadioGroup.check(R.id.rb_home);
}
private void switchFragmentByReplace(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fl_content, fragment);
transaction.commit();
}
public void showBottom() {
mRadioGroup.setVisibility(View.VISIBLE);
}
public void hideBottom() {
mRadioGroup.setVisibility(View.GONE);
}
private BackHandledFragment mBackHandedFragment; //当前屏幕可见的Fragment
@Override
public void setSelectedFragment(BackHandledFragment selectedFragment) {
this.mBackHandedFragment = selectedFragment;
}
private long pressTime = 0;
/**
* 对Back事件进行判断处理
*/
@Override
public void onBackPressed() {
//当前屏幕可见的Fragment为null
if (mBackHandedFragment == null || !mBackHandedFragment.onBackPressed()) {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
long time = System.currentTimeMillis();
if (time - pressTime > 2000) {
Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
pressTime = time;
} else {
super.onBackPressed(); //退出
// ActivityManager.getInstance().exitApp(this);
}
} else {
getSupportFragmentManager().popBackStack(); //fragment 出栈
}
}
}
}
Fragment需要继承抽象类BackHandledFragment,并覆写抽象方法onBackPressed(),在抽象方法中判断WebView是否可以返回到之前打开的网页
package com.example.mydemo;
import android.app.Dialog;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.JsPromptResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
/**
* Cerated by xiaoyehai
* Create date : 2019/11/21 17:13
* description :
*/
public class HomeFragment extends BackHandledFragment {
private WebView mWebView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
LinearLayout ll_container = view.findViewById(R.id.ll_container);
mWebView = new WebView(getActivity().getApplicationContext());
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
mWebView.setLayoutParams(layoutParams);
ll_container.addView(mWebView);
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setRenderPriority(WebSettings.RenderPriority.HIGH);
// 开启 DOM storage API 功能
settings.setDomStorageEnabled(true);
//开启 database storage API 功能
settings.setDatabaseEnabled(true);
//启用地理定位,默认为true
settings.setGeolocationEnabled(true);
settings.setUseWideViewPort(true);
settings.setTextZoom(100);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
// LogUtils.e("shouldOverrideUrlLoading: " + url);
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
//LogUtils.e("onPageStarted: " + url);
//showLoading();
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//hideLoading();
MainActivity mainActivity = (MainActivity) getActivity();
if (mWebView.canGoBack()) {
//LogUtils.e("onPageFinished: canGoBack");
mainActivity.hideBottom();
} else {
//LogUtils.e("onPageFinished: nocanGoBack");
mainActivity.showBottom();
}
}
});
// mWebView.loadUrl(homeUrl);
String url = "http://aa47.107a.224.42a/taojiaanzhu/";
String myServerUrl = "http://192.168.1.175:8080/tjz_h5/index.html";
mWebView.loadUrl(url);
//mWebView.loadUrl("file:///android_asset/tjz/index.html");
return view;
}
/**
* 判断WebView是否可以返回到之前打开的网页
*
* @return
*/
@Override
public boolean onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
Log.e("xyh", "webView.goBack()");
return true;
} else {
Log.e("xyh", "退出");
return false;
}
}
}