Làm cách nào để quay lại trang trước nếu nhấn nút quay lại trong WebView?


327

Tôi có một ứng dụng mà tôi có một WebView nơi tôi hiển thị một số trang web. Nó hoạt động, nhấp vào một liên kết trong trang web đi đến trang tiếp theo trong trang web bên trong ứng dụng của tôi. Nhưng khi tôi nhấp vào nút quay lại của điện thoại, nó sẽ đưa tôi thẳng vào ứng dụng của mình. Thay vào đó, tôi muốn quay lại trang trước trong trang web. Tôi có thể làm cái này như thế nào?

Đây là mẫu mã tôi đang sử dụng:

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

Câu trả lời:


520

Tôi sử dụng một cái gì đó như thế này trong các hoạt động của mình với 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);
}

Biên tập:

Để mã này hoạt động, bạn cần thêm một trường vào Activitychứa WebView:

private WebView mWebView;

Khởi tạo nó trong onCreate()phương thức và bạn nên đi.

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

1
Tôi có nên đặt mã đó không? theo tất cả mã của tôi? hoặc chỉ dưới loasUrl giống như buildinZoom?
zvzej

3
Bạn sẽ đặt nó bên trong hoạt động của mình, nhưng bên ngoài phương thức onCreate ().
Bọt biểnGuy

Khi tôi đặt mã của bạn, nó sẽ báo lỗi cho biến mWebView vì không có mã nguồn, tôi nên đặt biến đó ở đâu?
zvzej

4
thay vì finish()đặtreturn super.onKeyDown(keyCode, event)
Bostone

6
hoặc trên thực tế chỉ cần xóa toàn bộ elsekhối
Bostone

300

Nếu sử dụng Android 2.2 trở lên (hiện là hầu hết các thiết bị), đoạn mã sau sẽ giúp bạn có được những gì bạn muốn.

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

5
Đẹp. Tôi sử dụng một biến thể của câu trả lời này, nhưng không có khối "khác". Mặt khác, khi người dùng nhấn trở lại quá nhiều lần, họ kết thúc tại màn hình "bắt đầu" của ứng dụng trống, không có tùy chọn nào để người dùng di chuyển về phía trước.
George Armkeep

1
Đây có vẻ là câu trả lời thích hợp nhất. @CaffeineComa, có lẽ bạn chỉ có thể mã hóa màn hình bắt đầu ứng dụng của mình để không hiển thị trong lịch sử "hoạt động" của ứng dụng. Chỉ cần thêm android:noHistory="true"thuộc tính vào thứ <activity>bạn muốn, trong AndroidManifest.xml
LocalPCGuy

Có nên này return;không? Nó làm trong hướng dẫn đào tạo .
Keith

Cảm ơn rât nhiều!
DmitryKanunnikoff

Điều này hoạt động hoàn hảo trên Activity. (Y)
Waheed Nazir

113

Đây là giải pháp của tôi. Nó cũng hoạt động trong 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
ý kiến ​​của tôi, đây nên là câu trả lời thích hợp.
Arvin

2
Tại sao câu trả lời này phải là câu trả lời thích hợp? Bất kỳ vấn đề với hai câu trả lời hàng đầu?
ca9163d9

12
@ dc7a9163d9 một hoạt động có thể muốn có nhiều chế độ xem hoặc đối tượng phụ thuộc vào keyDown. câu trả lời này trừu tượng hóa sự cần thiết của hoạt động đối với sự phụ thuộc phím tắt thông qua webview (thiết kế tốt hơn). Ngoài ra, các ứng dụng mới hơn hầu như chỉ sử dụng các đoạn đối lập với các hoạt động và câu trả lời này hỗ trợ cho trường hợp sử dụng đó trái ngược với các ứng dụng khác
David T.

Tôi thích cách tiếp cận này. Thay vì toàn bộ hoạt động chỉ nghe WebView
davejoem

Đồng ý điều này là tốt hơn, vì vậy hoạt động chính không cần phải giữ WebView chỉ được sử dụng bởi các đoạn.
Jannik

18

Tham chiếu đầy đủ cho nút tiếp theo và thanh tiến trình: đặt lại và nút tiếp theo trong webview

Nếu bạn muốn quay lại trang sau khi nhấp vào nút quay lại của điện thoại, hãy sử dụng:

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

Bạn cũng có thể tạo nút quay lại tùy chỉnh như thế này:

btnback.setOnClickListener(new View.OnClickListener() {

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

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

16

Tập trung cũng nên được kiểm tra trong onBackPression

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

2
Âm thanh hợp lý, bạn có thể vui lòng giải thích tại sao?
SharpC

14

Tại sao không sử dụng onBackPressed()?

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

    // Go to the previous web page.
}

bởi vì chỉ sdk 2.2 trở lên hỗ trợ phương pháp này .. nó không hoạt động với sdk 1.6
Maher Abuthraa

1
otoh, Honeycomb và mới hơn không có khóa trở lại phần cứng, dẫn đến onKeyDown không bao giờ được gọi.
rác rưởi

10

Đây là một mã với xác nhận thoát:

@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

Trong kotlin:

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

webView - id của thành phần webview trong xml, nếu sử dụng tham chiếu tổng hợp.


2

Câu trả lời đầu tiên của FoamyGuy là đúng nhưng tôi có một số bổ sung; danh tiếng thấp không thể cho phép tôi bình luận. Nếu vì một số lý do, trang của bạn không tải được, hãy đảm bảo rằng bạn đặt cờ để ghi chú về lỗi và sau đó kiểm tra nó trên phần ghi đè onBackPress. Nếu không, canGoBack () của bạn sẽ được thực thi mãi mãi mà không hướng đến hoạt động trở lại thực tế nếu nó ở đó:

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

Bạn nên các thư viện sau trong lớp của bạn xử lý onBackKeyPression. canGoBack () kiểm tra xem webview có thể tham chiếu đến trang trước hay không. Nếu có thể thì hãy sử dụng hàm goBack () để tham chiếu trang trước đó (quay lại).

 @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

Đây là giải pháp của 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
}

0

Cách chính thức của 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


0

Nếu ai đó muốn xử lý backPress cho một webView bên trong một đoạn , thì anh ta có thể sử dụng mã bên dưới.

  1. Sao chép mã dưới đây vào Activitylớp của bạn (có chứa một đoạn 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. Sao chép mã này trong đoạn YourFragmentName

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

Ghi chú

  • Activity nên được thay thế bằng lớp Độ nhạy thực tế mà bạn đang sử dụng.
  • YourFragmentName nên được thay thế bằng tên của Fragment của bạn.
  • Khai báo webViewtrong YourFragmentNameđể nó có thể được truy cập từ bên trong hàm.

0

Bạn có thể thử điều này cho webview trong một đoạn:

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

sử dụng mã này để quay lại trang và khi trang cuối cùng xuất hiện thì hãy ra khỏi hoạt động

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

-5

Webview in Activity, Mã bên dưới hoạt động với tôi, Kết thúc hoạt động sau khi tải Url trong webview.in đã bật lại nó đi đến hoạt động trước đó

 webView = (WebView) findViewById(R.id.info_webView);
 webView.loadUrl(value);
 finish();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.