Jak wrócić do poprzedniej strony, jeśli przycisk Wstecz zostanie naciśnięty w WebView?

327

Mam aplikację, w której WebViewwyświetlam niektóre strony internetowe. Działa, kliknięcie linku na stronie przechodzi do następnej strony w witrynie w mojej aplikacji. Ale kiedy klikam przycisk Wstecz telefonu, przenosi mnie bezpośrednio do mojej aplikacji. Zamiast tego chcę wrócić do poprzedniej strony w witrynie. W jaki sposób mogę to zrobić?

Oto przykładowy kod, którego używam:

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
źródło

Odpowiedzi:

520

Używam czegoś takiego w swoich działaniach z WebView:

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

Edytować:

Aby ten kod działał, musisz dodać pole Activityzawierające WebView:

private WebView mWebView;

Zainicjuj to w onCreate()metodzie i powinieneś być dobry.

mWebView = (WebView) findViewById(R.id.webView);
FoamyGuy
źródło
1
czy powinienem umieścić ten kod? pod całym moim kodem? lub tuż pod loasUrl, tak jak wbudowany Zoom?
zvzej
3
Umieściłbyś go w swojej aktywności, ale poza metodą onCreate ().
FoamyGuy,
kiedy umieszczam kod, pojawia się błąd dla zmiennej mWebView, ponieważ nie jest oncreate, gdzie powinienem umieścić tę zmienną?
zvzej
4
zamiast finish()umieścićreturn super.onKeyDown(keyCode, event)
Bostone
6
lub po prostu usuń cały elseblok
Bostone
300

Jeśli używasz Androida 2.2 i nowszych (obecnie jest to większość urządzeń), poniższy kod zapewni Ci to, czego chcesz.

@Override
public void onBackPressed() {
    if (webView.canGoBack()) {
        webView.goBack();
    } else {
        super.onBackPressed();
    }
}
Kevin Westwood
źródło
5
Miły. Używam odmiany tej odpowiedzi, ale bez bloku „else”. W przeciwnym razie, gdy użytkownik naciska zbyt wiele razy, kończy się to pustym ekranem „startowym” aplikacji, bez możliwości przejścia do przodu.
George Armhold
1
To wygląda na najbardziej odpowiednią odpowiedź. @CaffeineComa, prawdopodobnie możesz po prostu zakodować ekran startowy aplikacji, aby nie wyświetlać się w historii „aktywności” aplikacji. Wystarczy dodać android:noHistory="true"atrybut w <activity>
żądanym
Czy to powinno return;? Tak jest w przewodniku szkoleniowym .
Keith,
Dziękuję Ci bardzo!
DmitryKanunnikoff
113

To jest moje rozwiązanie. Działa również we fragmencie.

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
źródło
16
to moja opinia, to powinna być właściwa odpowiedź.
Arvin,
2
Dlaczego ta odpowiedź powinna być właściwą odpowiedzią? Masz problem z dwiema głównymi odpowiedziami?
ca9163d9
12
@ dc7a9163d9 działanie może chcieć mieć kilka widoków lub obiektów zależnych od keyDown. ta odpowiedź uwydatnia potrzebę uzależnienia aktywności od działania za pomocą widoku internetowego (co jest lepszym projektem). także nowsze aplikacje prawie wyłącznie używają fragmentów w przeciwieństwie do działań, a ta odpowiedź obsługuje ten przypadek użycia w przeciwieństwie do innych
David T.
Lubię to podejście. Zamiast całej aktywności słuchanie tylko WebView
davejoem
Zgadzam się, że to jest lepsze, więc główna aktywność nie musi zawierać WebView używanego tylko przez fragmenty.
Jannik,
18

Pełne odniesienie do następnego przycisku i paska postępu: umieść przycisk wstecz i następny w widoku sieci

Jeśli chcesz przejść do tylnej strony po kliknięciu przycisku Wstecz telefonu, użyj tego:

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

Możesz również utworzyć niestandardowy przycisk Wstecz w następujący sposób:

btnback.setOnClickListener(new View.OnClickListener() {

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

            if (wv.canGoBack()) {
                wv.goBack();
            }
        }
    }); 
Parsania Hardik
źródło
16

Ustawianie ostrości powinno być również sprawdzane w BackPressed

    @Override
    public void onBackPressed() {
        if (mWebview.isFocused() && mWebview.canGoBack()) {
            mWebview.goBack();       
        } else {
            super.onBackPressed();
            finish();
        }
    }
Zar E Ahmer
źródło
2
Brzmi realistycznie, czy mógłbyś wyjaśnić dlaczego?
SharpC
14

Dlaczego nie użyć onBackPressed()?

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

    // Go to the previous web page.
}
Gyan alias Gary Buyn
źródło
ponieważ tylko sdk 2.2 i nowsze obsługują tę metodę. nie działa z sdk 1.6
Maher Abuthraa
1
otoh, Honeycomb i nowsze nie mają sprzętowego klucza powrotu, przez co onKeyDown nigdy nie jest wywoływany.
śmieciowy
10

oto kod z potwierdzeniem wyjścia:

@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
źródło
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
źródło
3

W kotlin:

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

webView - identyfikator komponentu webview w xml, jeśli używasz syntetycznego odwołania.

Wisznu Benny
źródło
2

Pierwsza odpowiedź FoamyGuy jest poprawna, ale mam kilka dodatków; niska reputacja nie pozwala mi na komentowanie. Jeśli z jakichś powodów strona nie ładuje się, upewnij się, że ustawiłeś flagę, aby zanotować błąd, a następnie sprawdź ją w zastąpieniu onBackPressed. W przeciwnym razie twoja canGoBack () zostanie na zawsze wykonana bez kierowania do faktycznej aktywności back, jeśli tam była:

//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
źródło
1

Poniższe biblioteki w klasie powinny obsługiwać funkcję onBackKeyPressed. canGoBack () sprawdza, czy widok sieci może odwoływać się do poprzedniej strony. Jeśli to możliwe, użyj funkcji goBack (), aby odwołać się do poprzedniej strony (cofnij się).

 @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
źródło
1

Oto rozwiązanie 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
źródło
0

Oficjalna droga Kotlin:

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
źródło
0

Jeśli ktoś chce obsłużyć backPressed dla webView wewnątrz fragmentu , może użyć poniższego kodu.

  1. Skopiuj poniższy kod do swojej Activityklasy (która zawiera 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. Skopiuj ten kod do fragmentu YourFragmentName

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

Notatki

  • Activity należy zastąpić faktyczną klasą Acacity, której używasz.
  • YourFragmentName powinien zostać zastąpiony nazwą twojego Fragmentu.
  • Zadeklarować webVieww YourFragmentNametak, że może on być dostępny z wewnątrz funkcji.
Faraz Ahmad
źródło
0

Możesz wypróbować to dla webview w fragmencie:

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
źródło
-2

użyj tego kodu, aby wrócić na stronę, a kiedy przyszła ostatnia strona, wyjdź z aktywności

 @Override
    public void onBackPressed() {
        super.onBackPressed();
        Intent intent=new Intent(LiveImage.this,DashBoard.class);
        startActivity(intent);
    }
Pradeep Kumar
źródło
-5

Webview in Activity, Poniższy kod działał dla mnie, Zakończ działanie po załadowaniu adresu URL do webview.in po cofnięciu go przejdź do poprzedniej aktywności

 webView = (WebView) findViewById(R.id.info_webView);
 webView.loadUrl(value);
 finish();
Libin Thomas
źródło