Comment revenir à la page précédente si le bouton de retour est enfoncé dans WebView?

327

J'ai une application dans laquelle j'ai un WebViewoù j'affiche des sites Web. Cela fonctionne, en cliquant sur un lien dans la page Web, vous accédez à la page suivante du site Web dans mon application. Mais lorsque je clique sur le bouton de retour du téléphone, cela m'amène directement dans mon application. Je veux plutôt revenir à la page précédente du site Web. Comment puis-je faire ceci?

Voici l'exemple de code que j'utilise:

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);
            }
        });
    }
}
zvzej
la source

Réponses:

520

J'utilise quelque chose comme ça dans mes activités avec 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);
}

Éditer:

Pour que ce code fonctionne, vous devez ajouter un champ au Activitycontenant la WebView:

private WebView mWebView;

Initialisez-le dans la onCreate()méthode et vous devriez être prêt à partir.

mWebView = (WebView) findViewById(R.id.webView);
FoamyGuy
la source
1
devrais-je placer ce code? sous tout mon code? ou juste sous le loasUrl tout comme le builtinZoom?
zvzej
3
Vous le mettriez dans votre activité, mais en dehors de la méthode onCreate ().
FoamyGuy
lorsque je place votre code, il me donne une erreur pour la variable mWebView car est hors du oncreate, où dois-je placer cette variable?
zvzej
4
au lieu de finish()mettrereturn super.onKeyDown(keyCode, event)
Bostone
6
ou en fait, il suffit de supprimer tout le elsebloc
Bostone
301

Si vous utilisez Android 2.2 et supérieur (qui est maintenant la plupart des appareils), le code suivant vous donnera ce que vous voulez.

@Override
public void onBackPressed() {
    if (webView.canGoBack()) {
        webView.goBack();
    } else {
        super.onBackPressed();
    }
}
Kevin Westwood
la source
5
Agréable. J'utilise une variante de cette réponse, mais sans le bloc "else". Sinon, lorsque l'utilisateur appuie trop de fois, il se retrouve sur un écran de démarrage d'application vide, sans possibilité pour l'utilisateur d'avancer.
George Armhold
1
Cela ressemble à la réponse la plus appropriée. @CaffeineComa, vous pourriez probablement simplement coder l'écran de démarrage de votre application pour ne pas l'afficher dans l'historique "d'activité" de l'application. Ajoutez simplement l' android:noHistory="true"attribut dans le que <activity>vous voulez, dans le AndroidManifest.xml
LocalPCGuy
Cela devrait-il return;? C'est le cas dans le guide de formation .
Keith
Merci beaucoup!
DmitryKanunnikoff
113

C'est ma solution. Il fonctionne également dans 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;
    }
});
petrnohejl
la source
16
ceci à mon avis, cela devrait être la bonne réponse.
Arvin
2
Pourquoi cette réponse devrait-elle être la bonne réponse? Un problème avec les deux premières réponses?
ca9163d9
12
@ dc7a9163d9 une activité peut vouloir avoir plusieurs vues ou objets qui dépendent de keyDown. cette réponse fait abstraction de la nécessité pour l'activité de réduire la dépendance via la visualisation Web (qui est une meilleure conception). aussi, les applications plus récentes utilisent presque exclusivement des fragments par opposition aux activités, et cette réponse prend en charge ce cas d'utilisation par opposition aux autres
David T.
J'aime cette approche. Au lieu de toute l'activité en écoutant juste la WebView
davejoem
D'accord, c'est mieux, donc l'activité principale n'a pas besoin de contenir une WebView uniquement utilisée par des fragments.
Jannik
18

Référence complète pour le bouton suivant et la barre de progression: remettre et bouton suivant dans la vue Web

Si vous souhaitez revenir à la dernière page lorsque vous cliquez sur le bouton de retour du téléphone, utilisez ceci:

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

Vous pouvez également créer un bouton de retour personnalisé comme celui-ci:

btnback.setOnClickListener(new View.OnClickListener() {

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

            if (wv.canGoBack()) {
                wv.goBack();
            }
        }
    }); 
Parsania Hardik
la source
16

La mise au point doit également être vérifiée sur BackPressed

    @Override
    public void onBackPressed() {
        if (mWebview.isFocused() && mWebview.canGoBack()) {
            mWebview.goBack();       
        } else {
            super.onBackPressed();
            finish();
        }
    }
Zar E Ahmer
la source
2
Cela semble plausible, pourriez-vous expliquer pourquoi?
SharpC
14

Pourquoi ne pas utiliser onBackPressed()?

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

    // Go to the previous web page.
}
Gyan alias Gary Buyn
la source
car seul sdk 2.2 et supérieur prend en charge cette méthode .. cela ne fonctionne pas avec sdk 1.6
Maher Abuthraa
1
otoh, Honeycomb et les plus récents n'ont pas de clé de retour matérielle, ce qui fait que onKeyDown n'est jamais appelé.
junkdog
10

voici un code avec confirmation de sortie:

@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();    
        }   
    }
Mohammed Ahmed
la source
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);
}
Mahesh
la source
3

En kotlin:

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

webView - id du composant webview en xml, si vous utilisez une référence synthétique.

vishnu benny
la source
2

La première réponse de FoamyGuy est correcte mais j'ai quelques ajouts; une mauvaise réputation ne me permet pas de faire des commentaires. Si, pour certaines raisons, votre page ne se charge pas, assurez-vous de définir un indicateur pour prendre note de l'échec, puis vérifiez-le sur la substitution onBackPressed. Sinon, votre canGoBack () sera toujours exécuté sans se diriger vers l'activité de retour réelle si elle était là:

//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();
    }
}
Ajowi
la source
1

Vous devez les bibliothèques suivantes de votre classe gérer le onBackKeyPressed. canGoBack () vérifie si la vue Web peut faire référence à la page précédente. Si c'est possible, utilisez la fonction goBack () pour référencer la page précédente (revenir en arrière).

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

Voici la solution 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
}
Gibolt
la source
0

Voie Kotlin officielle:

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

SANAT
la source
0

Si quelqu'un veut gérer backPressed pour une webView à l'intérieur d'un fragment , il peut utiliser le code ci-dessous.

  1. Copiez le code ci-dessous dans votre Activityclasse (qui contient un fragment 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. Copiez ce code dans le fragment YourFragmentName

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

Remarques

  • Activity doit être remplacé par la classe d’activité réelle que vous utilisez.
  • YourFragmentName devrait être remplacé par le nom de votre Fragment.
  • Déclarez webViewen YourFragmentNamesorte qu'il est accessible à partir de la fonction.
Faraz Ahmad
la source
0

Vous pouvez essayer ceci pour la visualisation Web dans un fragment:

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
}
Simbarashe Mupfururirwa
la source
-2

utilisez ce code pour revenir sur la page et lorsque la dernière page est venue, alors mettez hors service

 @Override
    public void onBackPressed() {
        super.onBackPressed();
        Intent intent=new Intent(LiveImage.this,DashBoard.class);
        startActivity(intent);
    }
Pradeep Kumar
la source
-5

Webview dans l'activité, le code ci-dessous a fonctionné pour moi, terminer l'activité après avoir chargé l'URL dans webview.in onbackpressed, aller à l'activité précédente

 webView = (WebView) findViewById(R.id.info_webView);
 webView.loadUrl(value);
 finish();
Libin Thomas
la source