Android 如何加上「;“回去”;WebView内部片段中的函数?

Android 如何加上「;“回去”;WebView内部片段中的函数?,android,android-fragments,android-webview,Android,Android Fragments,Android Webview,更新:已解决!问题与我的Viewpager而不是WebView有关。 我试图在片段中的WebView中添加一个“返回”函数。但我不知道如何: public final class TestFragment extends Fragment { static WebView mWeb; private View mContentView; @Override public View onCreateView(LayoutInflater inflater, Vi

更新:已解决!问题与我的Viewpager而不是WebView有关。

我试图在
片段
中的
WebView
中添加一个“返回”函数。但我不知道如何:

public final class TestFragment extends Fragment {

    static WebView mWeb;
    private View mContentView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState)
    {   
        mContentView = inflater.inflate(R.layout.webview, null);
        mWeb = (WebView)mContentView.findViewById(R.id.webview);

        WebSettings settings = mWeb.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setSupportZoom(false);
        mWeb.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        mWeb.getSettings().setBuiltInZoomControls(false);
        mWeb.loadUrl("myurl...");
        mWeb.setOnKeyListener(new OnKeyListener(){
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
                    mWeb.goBack();
                    return true;
                }
                return false;
            }
        });
    }   
}
我也试过这样的方法:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
        mWeb.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
return@setOnKeyListener true
另一个解决方案,但同样的问题:

@Override
public void onBackPressed()
{
    if(webView.canGoBack())
        webView.goBack();
    else
        super.onBackPressed();
}

有什么办法可以让它工作吗?

实际上,你不能直接在片段内部完成。可在
碎片活动
中覆盖
onBackPressed
。您可以做的是:

  • 在“活动”内重写“反压”
  • 调用
    onBackPressed
    时,检查当前片段的实例是否是显示
    webview
    的实例
  • 如果是,请询问
    片段
    是否可以返回
    webview
  • 如果不是,请拨打
    super
    或任何您需要的电话
  • 编辑:


    也许是android的限制。尝试使用处理程序执行此操作

    public final class TestFragment extends Fragment {
    
    
        static WebView mWeb;
        private View mContentView;
    
        private Handler handler = new Handler(){
            @Override
            public void handleMessage(Message message) {
                switch (message.what) {
                    case 1:{
                        webViewGoBack();
                    }break;
                }
            }
        };
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {   
    
            mContentView = inflater.inflate(R.layout.webview, null);
            mWeb = (WebView)mContentView.findViewById(R.id.webview);
    
            WebSettings settings = mWeb.getSettings();
            settings.setJavaScriptEnabled(true);
            settings.setSupportZoom(false);
            mWeb.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
            mWeb.getSettings().setBuiltInZoomControls(false);
            mWeb.loadUrl("myurl...");
            mWeb.setOnKeyListener(new OnKeyListener(){
    
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_BACK 
                            && event.getAction() == MotionEvent.ACTION_UP 
                            && mWeb.canGoBack()) {
                        handler.sendEmptyMessage(1);
                        return true;
                    }
    
                    return false;
                }
    
            });
    
        }   
    
        private void webViewGoBack(){
            mWeb.goBack();
        }
    }
    
    您可以通过以下方式完成此操作:

    • 活动中
      输入:

      // Set WebView
      
      public void setWebView(WebView web) {
      
          this.web = web;
      }
      
    • ActivityCreated()
      put之后的web片段中:

      ((您的活动)getActivity()).setWebView(webView)

    • 不要忘记从
      onCreateView()
      设置
      webView
      ,如下所示:

      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
              Bundle savedInstanceState) {
          webView = (WebView) inflater.inflate(R.layout.your_web_fragment, container,
                  false);
          return web;
      }
      

    我的解决方案是添加到公共方法中的片段

    public static boolean canGoBack(){
            return mWebView.canGoBack();
        }
    
        public static void goBack(){
            mWebView.goBack();
        }
    
    然后从活动中我打电话

    @Override
    public void onBackPressed() {
        if(webFragment.canGoBack()){
            webFragment.goBack();
        }else{
            super.onBackPressed();
        }
    
    }
    

    注意mwebview是静态的

    WebViewActivity.java
    中,我添加了一个方法:

    @Override
    public void onBackPressed() {
    
        WebViewFragment fragment = (WebViewFragment)
                getSupportFragmentManager().findFragmentById(R.id.fragmentContainer);
        if (fragment.canGoBack()) {
            fragment.goBack();
        } else {
            super.onBackPressed();
        }
    }
    
    WebViewFragment.java
    中,我添加了两种方法:

    public boolean canGoBack() {
        return mWebView.canGoBack();
    }
    
    public void goBack() {
        mWebView.goBack();
    }
    

    @OmidAmnivia回答正确您的应用程序崩溃的解决方案是

    @Override
    public void onBackPressed() {
    if(webFragment.isInitialized && webFragment.canGoBack()){
        webFragment.goBack();
    }else{
        super.onBackPressed();
    }
    }
    

    您必须检查您的类是否已初始化

    首先,在碎片中被压回去

     mContentView.setFocusableInTouchMode(true);
     mContentView.requestFocus();
     mContentView.setOnKeyListener( new OnKeyListener()
     {
       @Override
       public boolean onKey( View v, int keyCode, KeyEvent event )
      {
          if( keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack())
          {                                                    
                mWebView.goBack();
                return true;
          }
          return false;
      }
     } );
    

    希望它能起作用。

    @RomanBlack的答案给了我正确的想法,但由于我们使用了kotlin,我不得不稍微修改一下答案

    webView.setOnKeyListener { _, _, keyEvent ->
            if (keyEvent.keyCode == KeyEvent.KEYCODE_BACK && !webView.canGoBack()) {
                false
            } else if (keyEvent.keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == MotionEvent.ACTION_UP) {
                webView.goBack()
                true
            } else true
        }
    
    如果您想使用退货,您必须添加以下内容:

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
            mWeb.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
    
    return@setOnKeyListener true
    

    您可以检查以下代码:

        webView.canGoBack();
        webView.setOnKeyListener(new View.OnKeyListener() {
    
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK
                        && event.getAction() == MotionEvent.ACTION_UP
                        && webView.canGoBack()) {
                    webView.goBack();
                    return true;
                }
                return false;
            }
        });
    

    我创建了一个简单的界面:

    public interface IOnBackPressed {
        boolean onBackPressed();
    }
    
    在活动中:

    public class MyActivity extends Activity {
        @Override public void onBackPressed() {
        Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_container);
           if (!(fragment instanceof IOnBackPressed) || !((IOnBackPressed) fragment).onBackPressed()) {
              super.onBackPressed();
           }
        }
    }
    
    在片段中:

    public class MyFragment extends Fragment implements IOnBackPressed {
       @Override
        public boolean onBackPressed() {
            if (webview.canGoBack()) {
                webview.goBack();
                // backpress is not considered in the Activity
                return true;
            } else {
                // activity will act normal
                return false;
            }
        }
    }
    

    这就是我在我的应用程序中所做的。我使用back press事件,直到web视图可以返回。一旦网络视图无法返回,我会提示用户,若他继续按后退键,那个么应用程序将退出

    当webview无法返回时,它将为用户提供一个留在应用程序中的机会。我觉得它更人性化:

              //time passed between two back presses.
              private val TIME_INTERVAL = 200 
               // variable to keep track of last back press
              private var mBackPressed: Long = 0
    
    
            webView!!.requestFocus()
            webView.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
                if (keyCode == KeyEvent.KEYCODE_BACK
                        && event.action == MotionEvent.ACTION_UP
                      ) {
                    if(webView.canGoBack()) {
                        //go back in previous page
                        webView.goBack()
                        return@OnKeyListener true
                    }
                    else
                    {
                        if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis())
                        {   // dont consume back press and pass to super
                            return@OnKeyListener false
                        }
                        else {
                            // show hint for double back press
                            Toast.makeText(context, " Double Tap back button to exit the demo", Toast.LENGTH_SHORT).show();
                            mBackPressed = System.currentTimeMillis();
                            return@OnKeyListener true
                        }
                    }
                }
                return@OnKeyListener false
    
            })
    

    使用BackPressedDispatcher有一种简单的方法

    片段:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if(webView.canGoBack()){
                   webView.goBack()
                } else {
                    isEnabled = false
                    requireActivity().onBackPressed()
                }
            }
        }
        requireActivity().onBackPressedDispatcher.addCallback(this,callback)
    }
    
    override fun onBackPressed() {
        val fragment = supportFragmentManager.findFragmentByTag("WebViewFragment")
        if (WebViewFragment::class.java.isInstance(fragment)) {
            if (onBackPressedDispatcher.hasEnabledCallbacks()) {
                onBackPressedDispatcher.onBackPressed()
                return
            }
            super.onBackPressed()
        }
    }
    
    活动:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if(webView.canGoBack()){
                   webView.goBack()
                } else {
                    isEnabled = false
                    requireActivity().onBackPressed()
                }
            }
        }
        requireActivity().onBackPressedDispatcher.addCallback(this,callback)
    }
    
    override fun onBackPressed() {
        val fragment = supportFragmentManager.findFragmentByTag("WebViewFragment")
        if (WebViewFragment::class.java.isInstance(fragment)) {
            if (onBackPressedDispatcher.hasEnabledCallbacks()) {
                onBackPressedDispatcher.onBackPressed()
                return
            }
            super.onBackPressed()
        }
    }
    
    也许这些代码可以改进,但对我来说效果很好。欲了解更多信息,请访问。

    这在我的情况下有效

    public class FantasyFragment extends Fragment  implements SwipeRefreshLayout.OnRefreshListener {
    
    WebView webview;
    SwipeRefreshLayout swipeLayout;
    String currentUrl="https://www.stackoverflow.com/";
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View root = inflater.inflate(R.layout.fragment_stadium, container, false);
    
    
        swipeLayout = (SwipeRefreshLayout) root.findViewById(R.id.swipescreen);
        swipeLayout.setOnRefreshListener(this);
    
        return root;
    }
    
    @Override
    public void onStart() {
        super.onStart();
        LoadWeb();
    }
    
    public void LoadWeb() {
    
    
    
        webview = (WebView) getActivity().findViewById(R.id.webview786);
        swipeLayout.setRefreshing(true);
        webview.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
        webview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        webview.getSettings().setAppCacheEnabled(true);
    
        WebSettings webSettings = webview.getSettings();
        webSettings.setJavaScriptEnabled(true);
    
        webSettings.setDatabaseEnabled(true);
        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        webSettings.setUseWideViewPort(true);
        webSettings.setSavePassword(true);
        webSettings.setSaveFormData(true);
        webSettings.setEnableSmoothTransition(true);
    
        webview.loadUrl(currentUrl);
    
        webview.setWebViewClient(new WebViewClient() {
            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Snackbar.make(view, "Connection Error", Snackbar.LENGTH_LONG)
                        .setAction("Retry", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                LoadWeb();
                            }
                        }).show();
            }
            @Override
            public void onPageFinished(WebView view, String url) {
                swipeLayout.setRefreshing(false);
                currentUrl = url;
                super.onPageFinished(view, url);
            }
        });
    
        webview.canGoBack();
        webview.setOnKeyListener(new View.OnKeyListener() {
    
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK
                        && event.getAction() == MotionEvent.ACTION_UP
                        && webview.canGoBack()) {
                    webview.goBack();
                    return true;
                }
                return false;
            }
        });
    }
    @Override
    public void onRefresh() {
        LoadWeb();
    }
    }
    

    会发生什么?实现onBackPressed()的第三个选项适用于我,请确保您确实有一些东西要返回。问题是?我有一个非常相似的情况:)感谢这段代码,真的帮助我提供了一个快速解决问题的导航抽屉和片段webview。对我来说也是如此,这应该被选为答案!这是可行的,但是有一个缺陷。您只检测到了keyCode,而不是KeyEvent。因此,当你按下后退按钮时,你的on键将被呼叫两次,按下一次,向上一次。所以它应该是:如果(keyCode==KeyEvent.keyCode\u BACK&&event.getAction()==MotionEvent.ACTION\u UP){你能告诉我为什么要使用handler!