Come tornare alla pagina precedente se si preme il pulsante Indietro in WebView?


327

Ho un'app in cui ho un sito in WebViewcui visualizzo alcuni siti Web. Funziona, facendo clic su un collegamento nella pagina Web si passa alla pagina successiva nel sito Web all'interno della mia app. Ma quando faccio clic sul pulsante Indietro del telefono, mi porta direttamente nella mia app. Voglio invece tornare alla pagina precedente nel sito Web. Come posso fare questo?

Ecco l'esempio di codice che sto usando:

public class Webdisplay extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
        setContentView(R.layout.webdisplay);

        getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
                Window.PROGRESS_VISIBILITY_ON); 

        Toast loadingmess = Toast.makeText(this,
                "Cargando El Diario de Hoy", Toast.LENGTH_SHORT);
        loadingmess.show();

        WebView myWebView;

        myWebView = (WebView) findViewById(R.id.webview);
        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.loadUrl("http://www.elsalvador.com");
        myWebView.setWebViewClient(new WebViewClient());
        myWebView.setInitialScale(1);
        myWebView.getSettings().setBuiltInZoomControls(true);
        myWebView.getSettings().setUseWideViewPort(true);

        final Activity MyActivity = this;
        myWebView.setWebChromeClient(new WebChromeClient() 
        {
            public void onProgressChanged(WebView view, int progress)   
            {
                MyActivity.setTitle("Loading...");
                MyActivity.setProgress(progress * 100); 

                if(progress == 100)
                    MyActivity.setTitle(R.string.app_name);
            }
        });
    }
}

Risposte:


520

Uso qualcosa del genere nelle mie attività con WebViews:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (event.getAction() == KeyEvent.ACTION_DOWN) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                if (mWebView.canGoBack()) {
                    mWebView.goBack();
                } else {
                    finish();
                }
                return true;
        }

    }
    return super.onKeyDown(keyCode, event);
}

Modificare:

Affinché questo codice funzioni, è necessario aggiungere un campo al ActivityWebView contenente:

private WebView mWebView;

Inizializzalo con il onCreate()metodo e dovresti essere pronto.

mWebView = (WebView) findViewById(R.id.webView);

1
dove dovrei inserire quel codice? sotto tutto il mio codice? o appena sotto loasUrl proprio come builtinZoom?
zvzej,

3
Lo inseriresti nella tua attività, ma al di fuori del metodo onCreate ().
Foamy:

quando inserisco il tuo codice mi dà un errore per la variabile mWebView poiché è fuori dal oncreate, dove devo posizionare quella variabile?
zvzej

4
invece di finish()metterereturn super.onKeyDown(keyCode, event)
Bostone

6
o in effetti basta semplicemente rimuovere l'intero elseblocco
Bostone il

301

Se usi Android 2.2 e versioni successive (che ora sono la maggior parte dei dispositivi), il codice seguente ti fornirà ciò che desideri.

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

5
Bello. Uso una variante di questa risposta, ma senza il blocco "else". Altrimenti quando l'utente preme indietro troppe volte finiscono in una schermata di "avvio" dell'app vuota, senza possibilità per l'utente di andare avanti.
George Armhold,

1
Questa sembra la risposta più appropriata. @CaffeineComa, probabilmente potresti semplicemente codificare la schermata di avvio dell'app per non mostrarla nella cronologia delle "attività" dell'app. Aggiungi l' android:noHistory="true"attributo <activity>che desideri, in AndroidManifest.xml
LocalPCGuy il

Questo dovrebbe return;? Lo fa nella guida all'allenamento .
Keith,

Grazie mille!
DmitryKanunnikoff il

113

Questa è la mia soluzione Funziona anche in Fragment.

webView.setOnKeyListener(new OnKeyListener()
{
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event)
    {
        if(event.getAction() == KeyEvent.ACTION_DOWN)
        {
            WebView webView = (WebView) v;

            switch(keyCode)
            {
                case KeyEvent.KEYCODE_BACK:
                    if(webView.canGoBack())
                    {
                        webView.goBack();
                        return true;
                    }
                    break;
            }
        }

        return false;
    }
});

16
questa la mia opinione, questa dovrebbe essere la risposta corretta.
Arvin,

2
Perché questa risposta dovrebbe essere la risposta corretta? Qualche problema con le prime due risposte?
ca9163d9

12
@ dc7a9163d9 un'attività potrebbe voler avere più viste o oggetti che dipendono da KeyDown. questa risposta evita la necessità per l'attività di ridurre la dipendenza tramite webview (che è una progettazione migliore). inoltre, le app più recenti utilizzano quasi esclusivamente frammenti rispetto alle attività e questa risposta supporta tale caso d'uso rispetto agli altri
David T.

Mi piace questo approccio. Invece dell'intera attività ascoltando solo WebView
davejoem,

D'accordo, è meglio, quindi l'attività principale non deve contenere un WebView utilizzato solo dai frammenti.
Jannik,

18

Riferimento completo per il pulsante successivo e la barra di avanzamento: reinserisci e pulsante successivo in visualizzazione Web

Se vuoi tornare alla pagina posteriore quando fai clic sul pulsante Indietro del telefono, usa questo:

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

Puoi anche creare un pulsante Indietro personalizzato come questo:

btnback.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            if (wv.canGoBack()) {
                wv.goBack();
            }
        }
    }); 

16

Anche la messa a fuoco deve essere verificata su BackPress

    @Override
    public void onBackPressed() {
        if (mWebview.isFocused() && mWebview.canGoBack()) {
            mWebview.goBack();       
        } else {
            super.onBackPressed();
            finish();
        }
    }

2
Sembra plausibile, potresti spiegare perché?
SharpC,

14

Perché non usare onBackPressed()?

@Override
public void onBackPressed()
{
    // super.onBackPressed(); Do not call me!

    // Go to the previous web page.
}

perché solo sdk 2.2 e versioni successive supportano questo metodo .. non funziona con sdk 1.6
Maher Abuthraa,

1
otoh, Honeycomb e le versioni più recenti non dispongono di una chiave hardware indietro, per cui onKeyDown non viene mai chiamato.
junkdog

10

ecco un codice con conferma uscita:

@Override
    public void onBackPressed()
    {
        if(webView.canGoBack()){
            webView.goBack();
        }else{
            new AlertDialog.Builder(this)
            .setIcon(android.R.drawable.ic_dialog_alert)
            .setTitle("Exit!")
            .setMessage("Are you sure you want to close?")
            .setPositiveButton("Yes", new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    finish();    
                }

            })
            .setNegativeButton("No", null)
            .show();    
        }   
    }

6
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    // Check if the key event was the Back button and if there's history
    if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
        myWebView.goBack();
        return true;
    }
    // If it wasn't the Back key or there's no web page history, bubble up to the default
    // system behavior (probably exit the activity)
    return super.onKeyDown(keyCode, event);
}

3

In kotlin:

override fun onBackPressed() {
    when {
        webView.canGoBack() -> webView.goBack()
        else -> super.onBackPressed()
    }
}

webView - ID del componente webview in xml, se si utilizza il riferimento sintetico.


2

La prima risposta di FoamyGuy è corretta ma ho alcune aggiunte; una reputazione bassa non può permettermi di fare commenti. Se per alcuni motivi la tua pagina non viene caricata, assicurati di impostare un flag per prendere nota dell'errore e quindi controllalo sull'override di onBackPressed. Altrimenti canGoBack () verrà eseguito per sempre senza andare all'attività back effettiva se fosse presente:

//flag with class wide access 
public boolean ploadFailFlag = false;

//your error handling override
@Override
public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {
    onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString());
    ploadFailFlag = true;       //note this change 
    .....
    .....
}

//finally to the answer to this question:
@Override
public void onBackPressed() {
    if(checkinWebView.canGoBack()){
        //if page load fails, go back for web view will not go back - no page to go to - yet overriding the super 
        if(ploadFailFlag){
            super.onBackPressed();
        }else {
            checkinWebView.goBack();
        }
    }else {
        Toast.makeText(getBaseContext(), "super:", Toast.LENGTH_LONG).show();
        super.onBackPressed();
    }
}

1

Le seguenti librerie della tua classe gestiranno onBackKeyPressed. canGoBack () controlla se la visualizzazione Web può fare riferimento alla pagina precedente. Se è possibile, utilizzare la funzione goBack () per fare riferimento alla pagina precedente (tornare indietro).

 @Override
        public void onBackPressed() {
          if( mWebview.canGoBack()){
               mWebview.goBack(); 
           }else{
            //Do something else. like trigger pop up. Add rate app or see more app
           }
  }

1

Ecco la soluzione Kotlin:

override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
    if (event?.action != ACTION_UP || event.keyCode != KEYCODE_BACK) {
        return super.onKeyUp(keyCode, event)
    }

    if (mWebView.canGoBack()) {
        mWebView.goBack()
    } else {
        finish()
    }
    return true
}

0

Kotlin Way ufficiale:

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    // Check if the key event was the Back button and if there's history
    if (keyCode == KeyEvent.KEYCODE_BACK && myWebView.canGoBack()) {
        myWebView.goBack()
        return true
    }
    // If it wasn't the Back key or there's no web page history, bubble up to the default
    // system behavior (probably exit the activity)
    return super.onKeyDown(keyCode, event)
}

https://developer.android.com/guide/webapps/webview.html#NavigatingHistory


0

Se qualcuno vuole gestire backPressed per una webView all'interno di un frammento , allora può usare il codice seguente.

  1. Copia sotto il codice nella tua Activityclasse (che contiene un frammento YourFragmmentName)

    @Override
    public void onBackPressed() {
    List<Fragment> fragmentList = getSupportFragmentManager().getFragments();
    
    boolean handled = false;
    for(Object f: fragmentList) {
        if(f instanceof YourFragmentName) {
            handled = ((YourFragmentName)f).onBackPressed();
            if(handled) {
                break;
            }
        }
    }
    
    if(!handled) {
        super.onBackPressed();
    }

    }

  2. Copia questo codice nel frammento YourFragmentName

    public boolean onBackPressed() {
       if (webView.canGoBack()) {
           webView.goBack();
           return true;
       } else {
           return false;
       }
    }

Appunti

  • Activity deve essere sostituito con la classe di acidità attuale che si sta utilizzando.
  • YourFragmentName dovrebbe essere sostituito con il nome del tuo frammento.
  • Dichiarare webViewin YourFragmentNamemodo che sia possibile accedervi dall'interno della funzione.

0

Puoi provare questo per la visualizzazione Web in un frammento:

private lateinit var webView: WebView

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val root = inflater.inflate(R.layout.fragment_name, container, false)
    webView = root!!.findViewById(R.id.home_web_view)
    var url: String = "http://yoururl.com"
    webView.settings.javaScriptEnabled = true
    webView.webViewClient = WebViewClient()
    webView.loadUrl(url)
    webView.canGoBack()
    webView.setOnKeyListener{ v, keyCode, event ->
        if(keyCode == KeyEvent.KEYCODE_BACK && event.action == MotionEvent.ACTION_UP
            && webView.canGoBack()){
            webView.goBack()
            return@setOnKeyListener true
        }
        false
    }
    return root
}

-2

usa questo codice per tornare indietro nella pagina e quando è arrivata l'ultima pagina, allora vai fuori attività

 @Override
    public void onBackPressed() {
        super.onBackPressed();
        Intent intent=new Intent(LiveImage.this,DashBoard.class);
        startActivity(intent);
    }

-5

Webview in Activity, sotto il codice ha funzionato per me, Termina l'attività dopo aver caricato l'URL in webview.in dopo averlo premuto, vai all'attività precedente

 webView = (WebView) findViewById(R.id.info_webView);
 webView.loadUrl(value);
 finish();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.