Wie kann ich zur vorherigen Seite zurückkehren, wenn in WebView die Schaltfläche "Zurück" gedrückt wird?


327

Ich habe eine App, in der ich WebVieweinige Websites anzeigen kann. Es funktioniert, wenn Sie auf einen Link auf der Webseite klicken, gelangen Sie zur nächsten Seite der Website in meiner App. Wenn ich jedoch auf die Zurück-Schaltfläche des Telefons klicke, gehe ich direkt in meine App. Ich möchte stattdessen zur vorherigen Seite der Website zurückkehren. Wie kann ich das machen?

Hier ist das Codebeispiel, das ich verwende:

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

Antworten:


520

Ich verwende so etwas in meinen Aktivitäten mit 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);
}

Bearbeiten:

Damit dieser Code funktioniert, müssen Sie Activitydem WebView ein Feld hinzufügen:

private WebView mWebView;

Initialisieren Sie es in der onCreate()Methode und Sie sollten bereit sein zu gehen.

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

1
Wo soll ich diesen Code platzieren? unter meinem ganzen Code? oder einfach unter dem loasUrl wie beim eingebauten zoom?
Zvzej

3
Sie würden es in Ihre Aktivität einfügen, aber außerhalb der onCreate () -Methode.
FoamyGuy

Wenn ich Ihren Code platziere, wird mir ein Fehler für die Variable mWebView angezeigt, da diese nicht mehr in oncreate enthalten ist. Wo soll ich diese Variable platzieren?
Zvzej

4
statt zu finish()setzenreturn super.onKeyDown(keyCode, event)
Bostone

6
oder in der Tat einfach den ganzen elseBlock entfernen
Bostone

300

Wenn Sie Android 2.2 und höher verwenden (dies sind derzeit die meisten Geräte), erhalten Sie mit dem folgenden Code das, was Sie möchten.

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

5
Nett. Ich verwende eine Variation dieser Antwort, aber ohne den "else" -Block. Andernfalls wird der Benutzer, wenn er zu oft zurückdrückt, auf einem leeren Startbildschirm der App angezeigt, ohne dass der Benutzer die Möglichkeit hat, vorwärts zu gehen.
George Armhold

1
Dies scheint die am besten geeignete Antwort zu sein. @CaffeineComa, Sie könnten wahrscheinlich einfach Ihren App-Startbildschirm so codieren, dass er nicht im Aktivitätsverlauf der App angezeigt wird. Fügen Sie einfach android:noHistory="true"Attribut in der <activity>Sie wollen, in der AndroidManifest.xml
LocalPCGuy

Sollte das return;? Dies geschieht im Trainingsleitfaden .
Keith

Vielen Dank!
DmitryKanunnikoff

Dies funktioniert perfekt bei Aktivitäten. (Y)
Waheed Nazir

113

Das ist meine Lösung. Es funktioniert auch 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
Dies ist meiner Meinung nach die richtige Antwort.
Arvin

2
Warum sollte diese Antwort die richtige sein? Gibt es ein Problem mit den beiden wichtigsten Antworten?
ca9163d9

12
@ dc7a9163d9 Eine Aktivität möchte möglicherweise mehrere Ansichten oder Objekte haben, die von keyDown abhängen. Diese Antwort abstrahiert die Notwendigkeit, dass die Aktivität die Abhängigkeit über die Webansicht festlegt (was ein besseres Design ist). Außerdem verwenden neuere Apps fast ausschließlich Fragmente im Gegensatz zu Aktivitäten, und diese Antwort unterstützt diesen Anwendungsfall im Gegensatz zu den anderen
David T.

Ich mag diesen Ansatz. Anstelle der gesamten Aktivität hören Sie nur das WebView
Davejoem

Stimmen Sie zu, dass dies besser ist, sodass die Hauptaktivität keine WebView enthalten muss, die nur von Fragmenten verwendet wird.
Jannik

18

Vollständige Referenz für die nächste Schaltfläche und den Fortschrittsbalken: Zurücksetzen und nächste Schaltfläche in der Webansicht

Wenn Sie beim Klicken auf die Schaltfläche "Zurück" des Telefons zur Rückseite wechseln möchten, verwenden Sie Folgendes:

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

Sie können auch eine benutzerdefinierte Zurück-Schaltfläche wie folgt erstellen:

btnback.setOnClickListener(new View.OnClickListener() {

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

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

16

Die Fokussierung sollte auch in onBackPressed aktiviert sein

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

2
Klingt plausibel, können Sie bitte erklären, warum?
SharpC

14

Warum nicht verwenden onBackPressed()?

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

    // Go to the previous web page.
}

weil nur SDK 2.2 und höher diese Methode unterstützt .. es funktioniert nicht mit SDK 1.6
Maher Abuthraa

1
otoh, Honeycomb und neuere Versionen verfügen nicht über einen Hardware-Back-Key, sodass onKeyDown nie aufgerufen wird.
Junkdog

10

Hier ist ein Code mit Bestätigungs-Exit:

@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 der Webview-Komponente in XML, wenn eine synthetische Referenz verwendet wird.


2

Die erste Antwort von FoamyGuy ist richtig, aber ich habe einige Ergänzungen; Ein niedriger Ruf kann mir keine Kommentare erlauben. Wenn Ihre Seite aus bestimmten Gründen nicht geladen werden kann, stellen Sie sicher, dass Sie ein Flag setzen, um den Fehler zu notieren, und überprüfen Sie es dann bei der Überschreibung von onBackPressed. Andernfalls wird Ihr canGoBack () für immer ausgeführt, ohne zur eigentlichen Rückaktivität zu wechseln, wenn es dort war:

//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

Sie sollten die folgenden Bibliotheken in Ihrer Klasse mit onBackKeyPressed behandeln. canGoBack () prüft, ob die Webansicht auf die vorherige Seite verweisen kann. Wenn es möglich ist, verwenden Sie die Funktion goBack (), um auf die vorherige Seite zu verweisen (zurück).

 @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

Hier ist die Kotlin-Lösung:

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

Offizieller Kotlin Way:

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

Wenn jemand backPressed für eine WebView in einem Fragment verarbeiten möchte , kann er den folgenden Code verwenden.

  1. Kopieren Sie den folgenden Code in Ihre ActivityKlasse (die ein Fragment enthält 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. Kopieren Sie diesen Code in das Fragment YourFragmentName

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

Anmerkungen

  • Activity sollte durch die tatsächlich verwendete Acitivity-Klasse ersetzt werden.
  • YourFragmentName sollte durch den Namen Ihres Fragments ersetzt werden.
  • Deklarieren Sie webViewin, YourFragmentNamedamit Sie innerhalb der Funktion darauf zugreifen können.

0

Sie können dies für die Webansicht in einem Fragment versuchen:

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

Verwenden Sie diesen Code, um zur Seite zurückzukehren. Wenn die letzte Seite gekommen ist, wird die Aktivität eingestellt

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

-5

Webview in Aktivität, Der folgende Code hat für mich funktioniert. Beenden Sie die Aktivität, nachdem Sie die URL in webview.in onbackpressed auf die vorherige Aktivität zurückgesetzt haben

 webView = (WebView) findViewById(R.id.info_webView);
 webView.loadUrl(value);
 finish();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.