Как вернуться на предыдущую страницу, если в WebView нажата кнопка «Назад»?

328

У меня есть приложение, в котором у меня есть WebViewнесколько веб-сайтов. Это работает, щелкнув ссылку на веб-странице, можно перейти на следующую страницу веб-сайта в моем приложении. Но когда я нажимаю кнопку «Назад» на телефоне, это сразу приводит меня в мое приложение. Вместо этого я хочу вернуться на предыдущую страницу сайта. Как я могу это сделать?

Вот пример кода, который я использую:

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
источник

Ответы:

521

Я использую что-то подобное в своей деятельности с 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);
}

Редактировать:

Чтобы этот код работал, вам нужно добавить поле, Activityсодержащее WebView:

private WebView mWebView;

Инициализируйте его в onCreate()методе, и вы должны быть готовы.

mWebView = (WebView) findViewById(R.id.webView);
FoamyGuy
источник
1
где я должен разместить этот код? под всем моим кодом? или просто под loasUrl, как встроенный Zoom?
zvzej
3
Вы поместили бы это в свою деятельность, но вне метода onCreate ().
FoamyGuy
когда я размещаю ваш код, он выдает ошибку для переменной mWebView, так как она находится вне пределов создания, где мне разместить эту переменную?
zvzej
4
вместо того, чтобы finish()поставитьreturn super.onKeyDown(keyCode, event)
Бостоне
6
или на самом деле просто удалите весь elseблок
Bostone
301

Если вы используете Android 2.2 и выше (а это большинство устройств сейчас), следующий код даст вам то, что вы хотите.

@Override
public void onBackPressed() {
    if (webView.canGoBack()) {
        webView.goBack();
    } else {
        super.onBackPressed();
    }
}
Кевин Вествуд
источник
5
Ницца. Я использую вариант этого ответа, но без блока "else". В противном случае, когда пользователь нажимает слишком много раз назад, он оказывается на пустом «стартовом» экране приложения, и у пользователя нет возможности двигаться вперед.
Джордж Армгольд
1
Это выглядит как наиболее подходящий ответ. @CaffeineComa, вы могли бы просто кодировать стартовый экран своего приложения, чтобы оно не отображалось в истории активности приложения. Просто добавьте android:noHistory="true"атрибут в <activity>
нужное
Должен ли это return;? Это делается в учебном пособии .
Кит
Большое спасибо!
Дмитрий Канунниково
113

Это моё решение. Это работает также во Фрагменте.

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
источник
16
это мое мнение, это должен быть правильный ответ.
Арвин
2
Почему этот ответ должен быть правильным ответом? Любая проблема с двумя верхними ответами?
ca9163d9
12
@ dc7a9163d9 действие может хотеть иметь несколько представлений или объектов, которые зависят от keyDown. В этом ответе абстрагируется от необходимости действий по выявлению зависимости через веб-просмотр (что является лучшим дизайном). Кроме того, новые приложения почти исключительно используют фрагменты в отличие от действий, и этот ответ поддерживает этот вариант использования в отличие от других
Дэвид Т.
Мне нравится этот подход. Вместо всей активности слушаю только WebView
davejoem
Согласитесь, это лучше, поэтому основное действие не должно содержать WebView, который используется только фрагментами.
Янник
18

Полная ссылка на следующую кнопку и индикатор выполнения: в веб-просмотре нажмите кнопку «Назад» и «Следующая»

Если вы хотите перейти на обратную страницу, когда нажмете кнопку «Назад» на телефоне, используйте это:

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

Вы также можете создать пользовательскую кнопку возврата, как это:

btnback.setOnClickListener(new View.OnClickListener() {

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

            if (wv.canGoBack()) {
                wv.goBack();
            }
        }
    }); 
Парсания Хардик
источник
16

Фокусировка также должна быть проверена на BackPress.

    @Override
    public void onBackPressed() {
        if (mWebview.isFocused() && mWebview.canGoBack()) {
            mWebview.goBack();       
        } else {
            super.onBackPressed();
            finish();
        }
    }
Zar E Ahmer
источник
2
Звучит правдоподобно, не могли бы вы объяснить, почему?
SharpC
14

Почему бы не использовать onBackPressed()?

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

    // Go to the previous web page.
}
Гьян ака Гари Буйн
источник
потому что только SDK 2.2 и выше поддерживает этот метод .. он не работает с SDK 1.6
Maher Abuthraa
1
ооо, у Honeycomb и новее нет аппаратного ключа возврата, в результате чего onKeyDown никогда не вызывается.
Junkdog
10

Вот код с подтверждением выхода:

@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

В котлин:

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

webView - идентификатор компонента webview в xml, если используется синтетическая ссылка.

Вишну Бенни
источник
2

Первый ответ от FoamyGuy правильный, но у меня есть некоторые дополнения; низкая репутация не может позволить мне делать комментарии. Если по каким-либо причинам ваша страница не загружается, убедитесь, что вы установили флажок, чтобы принять к сведению сбой, а затем проверьте его в переопределении onBackPressed. В противном случае ваш canGoBack () будет всегда выполняться без перехода к действию back, если оно было там:

//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
источник
1

Следующие библиотеки вашего класса должны обрабатывать onBackKeyPressed. canGoBack () проверяет, может ли веб-просмотр ссылаться на предыдущую страницу. Если это возможно, используйте функцию goBack () для ссылки на предыдущую страницу (возврат).

 @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

Вот решение 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
источник
0

Официальный путь 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
источник
0

Если кто-то хочет обработать backPressed для webView внутри фрагмента , он может использовать приведенный ниже код.

  1. Скопируйте приведенный ниже код в свой Activityкласс (который содержит фрагмент 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. Скопируйте этот код во фрагмент YourFragmentName

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

Ноты

  • Activity должны быть заменены фактическим классом Acctivity, который вы используете.
  • YourFragmentName следует заменить на название вашего фрагмента.
  • Признаться webViewв YourFragmentNameтак что она может быть доступна из функции.
Фараз Ахмад
источник
0

Вы можете попробовать это для веб-просмотра во фрагменте:

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

используйте этот код, чтобы вернуться на страницу, а когда пришла последняя страница, выйти из активности

 @Override
    public void onBackPressed() {
        super.onBackPressed();
        Intent intent=new Intent(LiveImage.this,DashBoard.class);
        startActivity(intent);
    }
Прадип Кумар
источник
-5

Webview в Activity, код ниже работал для меня, Завершите действие после загрузки URL-адреса в webview.in, после чего нажмите на него, чтобы перейти к предыдущему действию.

 webView = (WebView) findViewById(R.id.info_webView);
 webView.loadUrl(value);
 finish();
Либин Томас
источник