ACTUALIZACIÓN: Solucionado! Problema estaba relacionado con mi Viewpager no WebView.

Estoy tratando de agregar un «volver Atrás» la función de mi WebView que está dentro de un Fragment. Pero no puedo averiguar cómo:

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

También he probado algo como:

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

Otra solución, pero con el mismo problema:

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

Alguna idea de cómo conseguir este trabajo?

InformationsquelleAutor Markus Rubey | 2012-05-17

11 Comentarios

  1. 46

    Tal vez su android restricción. Trate de hacer esto utilizando el controlador.

    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();
        }
    }
    • mWeb.setOnKeyListener hizo el truco para mí, Muchas Gracias
    • Trabajó también para mí, Este debe ser seleccionado como respuesta!
    • esto funciona, pero tiene un defecto. Estás sólo detecta el código de la tecla, no la KeyEvent. Así que cuando usted pulsa el botón atrás, estás onKey le llamó dos veces, en el downpress y uno para el de arriba. Por lo que debe ser: if (keyCode == KeyEvent.KEYCODE_BACK && evento.getAction() == MotionEvent.ACTION_UP) {
    • me puedes decir ¿por qué utilizar el controlador.sin controlador que no será posible
  2. 21

    Realmente no se puede hacer directamente en el interior del fragmento. El onBackPressed puede ser reemplazado en el FragmentActivity. Lo que puedes hacer es:

    1. Reemplazar el onBackPressed dentro de la actividad.
    2. Cuando el onBackPressed se llama, compruebe si la instancia de la actual fragmento es el ejemplo, mostrando el webview.
    3. Si es así, pregunte el fragment si el webview puede ir hacia atrás.
    4. si no es así, llame a la super o lo que usted necesita

    Edición:

     @Override
     public void onBackPressed() {
           Fragment webview = getSupportFragmentManager().findFragmentByTag("webview");
           if (webview instanceof MyWebViewFragment) {
                  boolean goback = ((MyWebViewFragment)webview).canGoBack();
                  if (!goback)
                    super.onBackPressed();
           }
     }
    • Gracias por este código, realmente me ayudó a proporcionar una solución rápida a los problemas que estaba teniendo con un cajón de navegación y fragmento de webview.
  3. 17

    Puede comprobar este código :

        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;
            }
        });
    • Muchas gracias….
    • Gracias…., su código de trabajo para webview en el interior del fragmento para mí
    • mejor respuesta hasta ahora, funciona como debe, gracias.
    • GRACIAS! Funciona a la perfección.
  4. 6

    En WebViewActivity.java, he añadido el método 1:

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

    En WebViewFragment.java, he añadido 2 métodos:

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

    mi solución fue en el fragmento que he añadido a los métodos públicos de

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

    a continuación, a partir de la actividad que yo llamo

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

    nota La mwebview es estática

  6. 2

    usted puede hacer esto :

    • en el Activity poner :

      //Set WebView
      
      public void setWebView(WebView web) {
      
          this.web = web;
      }
    • en la web fragmento después de ActivityCreated() poner:

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

    • No olvide ajustar webView de la onCreateView() como estos:

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

    @OmidAmnivia respuesta es correcta su aplicación a la solución a la crisis es

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

    Usted tiene que comprobar si la clase ha sido inicializada o no.

  8. 1

    @RomanBlack la respuesta que me dio la idea de derecho, pero ya que el uso de kotlin tuve que adaptar la respuesta un poco.

    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
        }

    si quieres hacerlo con los retornos, usted tiene que agregar algo como:

    return@setOnKeyListener true
  9. 1

    He creado con una interfaz simple:

    public interface IOnBackPressed {
        boolean onBackPressed();
    }

    de la Actividad:

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

    en el Fragmento:

    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;
            }
        }
    }
  10. 1

    Esta es la forma en que lo hice en mi aplicación. Puedo consumir de nuevo evento de prensa hasta la vista web puede ir hacia atrás. Una vez en la web de la vista de peralte de volver muestro sugerencia al usuario de que si continúan presionando de nuevo, a continuación, la aplicación va a salir.

    Va a dar al usuario la oportunidad de permanecer en su aplicación cuando webview puedo ir de nuevo. Me sentía más amigable para el usuario:

              //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
    
            })
  11. 0

    Primero de todos volver presionado en el fragmento

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

    espero que trabaja.

Dejar respuesta

Please enter your comment!
Please enter your name here