36

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

WebView我正在尝试向我的内部添加一个“返回”功能Fragment。但我不知道如何:

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

另一个解决方案但同样的问题:

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

任何想法如何让这个工作?

4

14 回答 14

54

也许它的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();
    }
}
于 2012-05-17T07:46:18.417 回答
33

您可以检查此代码:

    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;
        }
    });
于 2017-12-08T08:14:12.427 回答
23

其实你不能直接在片段里面做。onBackPressed可以在FragmentActivity. 你可以做的是:

  1. 覆盖onBackPressed活动内部。
  2. 调用时 onBackPressed,检查当前片段的实例是否是显示webview.
  3. 如果是,请询问fragment是否webview可以返回。
  4. 如果不是,请致电super或任何您需要的

编辑:

 @Override
 public void onBackPressed() {
       Fragment webview = getSupportFragmentManager().findFragmentByTag("webview");
       if (webview instanceof MyWebViewFragment) {
              boolean goback = ((MyWebViewFragment)webview).canGoBack();
              if (!goback)
                super.onBackPressed();
       }
 }
于 2012-05-17T07:30:35.773 回答
8

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

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;
        }
    }
}
于 2018-06-26T13:46:52.320 回答
7

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

@Override
public void onBackPressed() {

    WebViewFragment fragment = (WebViewFragment)
            getSupportFragmentManager().findFragmentById(R.id.fragmentContainer);
    if (fragment.canGoBack()) {
        fragment.goBack();
    } else {
        super.onBackPressed();
    }
}

WebViewFragment.java中,我添加了 2 种方法:

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

public void goBack() {
    mWebView.goBack();
}
于 2014-10-19T10:07:49.917 回答
6

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

如果你想用退货来做到这一点,你必须添加类似的东西:

return@setOnKeyListener true
于 2017-05-30T06:14:15.747 回答
5

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()
    }
}

也许这些代码可以改进,但对我来说效果很好。欲了解更多信息,请访问此处

于 2020-04-02T12:07:15.623 回答
3

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

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 是静态的

于 2014-06-17T14:59:03.967 回答
2

你可以这样做:

  • Activity投入:

    // Set WebView
    
    public void setWebView(WebView web) {
    
        this.web = web;
    }
    
  • ActivityCreated()放置后的网络片段中:

    ((Your_Activity) getActivity()).setWebView(webView);

  • 不要忘记webViewonCreateView()这些设置:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        webView = (WebView) inflater.inflate(R.layout.your_web_fragment, container,
                false);
        return web;
    }
    
于 2012-09-17T12:45:47.590 回答
1

这就是我在我的应用程序中所做的。我消费后按事件,直到 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

        })
于 2019-01-29T10:44:13.977 回答
1

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

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

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

于 2015-10-03T21:53:17.837 回答
0

最简单的答案是直接setOnKeyListeneron进入 webView 本身:

webView.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey( View v, int keyCode, KeyEvent event ) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if( keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()){
                webView.goBack();
                return true;
            }
        }
        return false;
    }
});
于 2022-02-27T15:46:04.687 回答
0

首先回到片段中

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

希望它会起作用。

于 2017-05-05T09:54:54.497 回答
0

这在我的情况下有效

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();
}
}
于 2020-05-06T00:27:21.233 回答