Як повернутися до попередньої сторінки, якщо в WebView натиснуто кнопку назад?


327

У мене є додаток, в якому 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);
            }
        });
    }
}

Відповіді:


520

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

1
я повинен був розмістити цей код? під усім моїм кодом? або просто під loasUrl так само, як вбудований Zoom?
zvzej

3
Ви розміщуєте його всередині своєї діяльності, але поза методом onCreate ().
FoamyGuy

коли я розміщую ваш код, це дає мені помилку для змінної mWebView, оскільки вона не створена, де я повинен розмістити цю змінну?
zvzej

4
замість finish()поставитиreturn super.onKeyDown(keyCode, event)
Бостон

6
або насправді просто видаліть цілий elseблок
Bostone

300

Якщо ви користуєтесь Android 2.2 і вище (який зараз більшість пристроїв), наступний код отримає вам те, що ви хочете.

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

5
Приємно. Я використовую варіацію цієї відповіді, але без блоку "else". В іншому випадку, коли користувач натискає назад занадто багато разів, вони опиняються на порожньому екрані «запуску» програми, без можливості користувача рухатися вперед.
Джордж Армхолд

1
Це виглядає як найбільш відповідна відповідь. @CaffeineComa, ви, ймовірно, можете просто кодувати свій початковий екран програми, щоб не відображати в історії програми "активність" програми. Просто додайте android:noHistory="true"атрибут у <activity>потрібне вам, в AndroidManifest.xml
LocalPCGuy

Це повинно бути return;? Це робиться у навчальному посібнику .
Кіт

Дуже дякую!
ДмитроКануннікофф

113

Це моє рішення. Він також працює у 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
це моя думка, це має бути правильною відповіддю.
Арвін

2
Чому ця відповідь має бути правильною відповіддю? Будь-яке питання з двома найкращими відповідями?
ca9163d9

12
@ dc7a9163d9 діяльність може мати кілька представлень даних або об'єктів, які залежать від keyDown. ця відповідь абстрагує необхідність діяльності для зменшення залежності від клавіатури через веб-перегляд (що є кращим дизайном). також новіші програми майже виключно використовують фрагменти на відміну від діяльності, і ця відповідь підтримує цей випадок на відміну від інших
David T.

Мені подобається такий підхід. Замість усієї активності слухайте лише WebView
davejoem

Погодьтеся, це краще, тому основна діяльність не потребує вмісту WebView, використовуваного лише фрагментами.
Jannik

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

Фокусування також слід перевірити в onBackPress

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

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
otoh, Honeycomb та новіші не мають апаратного ключа назад, внаслідок чого onKeyDown ніколи не викликається.
мотлох

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 правильна, але я маю деякі доповнення; низька репутація не може дозволити мені робити коментарі. Якщо з певних причин ваша сторінка не завантажується, переконайтеся, що ви встановили прапор, щоб взяти до відома про помилку, а потім перевірте його на перезапис onBackPress. В іншому випадку ваш canGoBack () буде назавжди виконаний, не переходячи до фактичної задньої активності, якщо він був там:

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

Ви повинні наступні бібліотеки вашого класу обробляти onBackKeyPress. 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

Ось рішення Котліна:

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

Офіційний шлях Котліна:

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

Якщо хтось хоче обробити backPress для веб-перегляду всередині фрагмента , він може використовувати код нижче.

  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 слід замінити фактичним класом активності, який ви використовуєте.
  • 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

Веб-перегляд у діяльності, внизу код працює для мене. Закінчіть діяльність після завантаження URL-адреси в webview.in, натиснувши її, перейдіть до попередньої діяльності

 webView = (WebView) findViewById(R.id.info_webView);
 webView.loadUrl(value);
 finish();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.