Estimated reading time: 7 minutes
A WebView is an embeddable browser that helps a native application, such as Android, to display web content. If you are writing an application that needs to deliver a web content or show a web page as a part of a client application, you can do it smoothly and efficiently using WebView.
According to the Android Studio documentation, the WebView
class is an extension of Android’s View
class that allows you to display web pages as a part of your activity layout. It does not include any features of a fully developed web browser, such as navigation controls or an address bar. All that WebView
does, by default, is show a web page.
In this article, we shall see how to:
Let us begin …
implementation 'com.google.android.material:material:1.0.0'
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_behavior="@string/appbar_scrolling_view_behavior">
<WebView
android:id="@+id/web"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
style="?android:attr/progressBarStyle"
/>
</RelativeLayout>
public class MainActivity extends AppCompatActivity {
WebView webView;
ProgressBar progressBar;
SwipeRefreshLayout swipeRefreshLayout;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();
webView = findViewById(R.id.web);
progressBar = findViewById(R.id.progress);
swipeRefreshLayout = findViewById(R.id.swipe);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSupportZoom(false);
webView.getSettings().setDomStorageEnabled(true);
webView.setWebViewClient(new myWebViewclient());
webView.loadUrl("http://codeflarelimited.com");
}
}
Here we setting up our basic WebView and just passing the url we want to wrap. Notice also that we have initialized the SwipeRefreshLayout, and that’s all we are doing here. We need to make it show and dismiss it when the page is fully loaded.
So we add the following code:
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
webView.loadUrl("http://codeflarelimited.com");
}
}, 3000);
}
});
swipeRefreshLayout.setColorSchemeColors(
getResources().getColor(android.R.color.holo_blue_bright),
getResources().getColor(android.R.color.holo_orange_dark),
getResources().getColor(android.R.color.holo_green_dark),
getResources().getColor(android.R.color.holo_red_dark)
);
}
Notice we are also using WebViewClient. The WebViewClient allows us to handle navigation inside the WebView and to also handle the various events generated by the WebView. It is also in this WebViewClient block that we want to check for errors, network errors, SSL errors, etc.
We want to be able to handle errors in a nice and responsible way. So we’ll add the following code:
public class myWebViewclient extends WebViewClient{
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(getApplicationContext(), "No internet connection", Toast.LENGTH_LONG).show();
webView.loadUrl("file:///android_asset/lost.html");
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
handler.cancel();
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}
}
Now, let us explain what’s happening here. First we’re handling navigation here within the WebVeiw because of this line of code:
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
This ensures that whatever url that is loaded in the WebView opens up in the WebVeiw and does not navigate away or open up chrome or other web browser.
Next, we have the onReceivedError method. This is where we check for error, and to handle that we have created an offline html file that will load when the app encounters a network failure.
The default behaviour of webView applications, especially in Android, is that once you press the back button it closes the application. But what if we have visited several pages and we want to go back to the previous page?
So we need to handle the back navigation and just say if the webView has previous pages and canGoBack(), let it just goBack(). We’ll add the following code as well:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
import androidx.appcompat.app.AppCompatActivity;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
WebView webView;
ProgressBar progressBar;
SwipeRefreshLayout swipeRefreshLayout;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();
webView = findViewById(R.id.web);
progressBar = findViewById(R.id.progress);
swipeRefreshLayout = findViewById(R.id.swipe);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSupportZoom(false);
webView.getSettings().setDomStorageEnabled(true);
webView.setWebViewClient(new myWebViewclient());
webView.loadUrl("http://codeflarelimited.com");
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
webView.loadUrl("http://codeflarelimited.com");
}
}, 3000);
}
});
swipeRefreshLayout.setColorSchemeColors(
getResources().getColor(android.R.color.holo_blue_bright),
getResources().getColor(android.R.color.holo_orange_dark),
getResources().getColor(android.R.color.holo_green_dark),
getResources().getColor(android.R.color.holo_red_dark)
);
}
public class myWebViewclient extends WebViewClient{
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(getApplicationContext(), "No internet connection", Toast.LENGTH_LONG).show();
webView.loadUrl("file:///android_asset/lost.html");
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
handler.cancel();
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
First, we need to create an assets folder like so:
Next, we create an image folder right inside the assets folder and just put our image there. This image will portray a network failure. I have decided to call my own gone.png. Feel free to use any image of your choice:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Connection Failed</title>
<style>
body {
display: inline-block;
background: #00AFF9 url('img/gone.png') center/cover no-repeat;
height: 100vh;
margin: 0;
color: white;
}
h1 {
margin: .8em 3rem;
font: 4em Roboto;
}
p {
display: inline-block;
margin: .2em 3rem;
font: 2em Roboto;
}
</style>
</head>
<body>
<center>
<h2 style="text-align:center;padding:5px;color:#d9534f">The network failed</h2>
<h2 style="text-align:center;padding:5px;color:#d9534f">Check your network connection and swipe to refresh </h2>
</center>
</body>
</html>
See 7 Reasons Why You Should Learn Software Development
You need to add instructions for internet connection in your AndroidManifest.xml file otherwise the webView won’t show. This way we can request permission to use the internet
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
Apple is reportedly developing a new smart doorbell camera with Face ID technology to unlock…
This month has been packed for Google as it ramps up efforts to outshine OpenAI…
OpenAI has been rolling out a series of exciting updates and features for ChatGPT, and…
A financially motivated phishing campaign has targeted around 300 organizations, with over 4,000 spoofed emails…
Hackers are exploiting Microsoft Teams to deceive users into installing remote access tools, granting attackers…
Data plays an essential role in our lives. We each consume and produce huge amounts…