Fragment内放置WebView,点击手机返回键,并返回之前打开的网页

问题

Fragment内放置WebView,点击手机返回键,如果不做处理,会直接退出Activity,不能返回之前打开的网页。

创建一个抽象类BackHandledFragment

首先创建一个抽象类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);
    }

}

创建BackHandledIntegerface接口

宿主FragmentActivity需要实现BackHandledIntegerface,子Fragment会通过该接口告诉宿主FragmentActivity自己是当前屏幕可见的Fragment。

public interface BackHandledInterface {

    void setSelectedFragment(BackHandledFragment selectedFragment);
}

宿主FragmentActivity需要实现BackHandledIntegerface接口

在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

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

    }
}

你可能感兴趣的:(android)