When we think about the web for native mobile applications we tend to think of the web as a data transfer mechanism. We talk about the cloud, JSON, XML, and RSS; all of which are important but often we need the web as more than the backbone of information. There are a couple of reasons you may want to display web content in your app instead of a native view:
- You want to show external content without leaving your app.
- You have dynamic content whose structure changes often.
- You want to display legal pages (terms of service, end user license agreements, etc) directly from your site.
Today I'm going to start a series on the Android WebView. In this post we'll talk about the basic's of setting up a WebView to display web content in your app. In other posts I'll explain how to interact with web content via Javascript from your app as well as interacting with your app from Javascript. Finally I'll go over some gotchas or hurdles that it's important to be aware of when using a web view in your app.
Initializing the WebView
Initializing the WebView should be done when your Activity or Fragment is created. While the default settings the WebView uses will probably work for most basic web pages, you can be more explicit about how your WebView acts. You specify your preferences using the WebSettings object on your WebView.
Obtaining your WebView's settings is as simple as calling getSettings() on the WebView object. Here's an example of changing some of the default WebView settings:
private void initializeWebView(Bundle savedInstanceState)
{
/** make sure you have a WebView in your layout with the id: browser **/
WebView browser = (WebView)getView().findViewById(R.id.browser);
// I like my scroll bars inside the content
browser.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
// allow web pages to execute Javascript.
browser.getSettings().setJavaScriptEnabled(true);
// if you know your web pages use a different encoding than utf-8 you can change it.
browser.getSettings().setDefaultTextEncodingName("utf-8");
// Start with content zoomed all the way out.
browser.getSettings().setLoadWithOverviewMode(true);
// Allow zooming with the default zoom controls
browser.getSettings().setSupportZoom(true);
browser.getSettings().setBuiltInZoomControls(true);
// Change how the web page is laid out.
// See WebSettings.LayoutAlgorithm for more detail.
browser.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
// Allow the HTML viewport meta tag to specify the width
browser.getSettings().setUseWideViewPort(true);
// Used to handle external interactions. More details below.
browser.setWebChromeClient(this.getWebChromeClient());
// Used to handle page events. More details below.
browser.setWebViewClient(this.getWebViewClient());
}
Loading A Web Page
Once you have a WebView added to your app displaying web pages is as simple as calling loadUrl on the WebView. For example:
private void loadWebPage(String url)
{
/** make sure you have a WebView in your layout with the id: browser **/
WebView browser = (WebView)getView().findViewById(R.id.browser);
browser.loadUrl(url);
}
Loading HTML Directly
Loading web data into your page doesn't have to be done using a remote URL. If you already have the HTML content you'd like to display (possibly from an RSS feed or offline content), you can do so very easily by first converting the content to Base64 and then creating a data URI to display the content. For example, you can generate a url for HTML content you already have that the WebView can display as follows:
private String getUrlFromHTML(String html)
{
String base64Data = Base64.encodeToString(html.getBytes(), Base64.DEFAULT);
return String.format("data:text/html;charset=utf-8;base64,%s", base64Data);
}
Advanced Browser Features
Handling Web Page Life-cycle and Other Events
There are several events associated with the web page life-cycle. For example there are events associated with web page loading being started/stopped. There are also events for web page errors as well as a login request from the web page. These web page events are handled via a WebViewClient. Your browser should, at a minimum, provide feedback to the user when a web page starts loading and when it stops loading. Here's an example of how you can handle those events:
protected WebViewClient getWebViewClient()
{
return new WebViewClient()
{
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon)
{
/** provide feedback using a spinner or some other dialog to
the user to let them know that you're doing some work **/
}
@Override
public void onPageFinished(WebView view, String url)
{
/** hide the feedback that was provided to the user **/
}
};
}
{
return new WebViewClient()
{
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon)
{
/** provide feedback using a spinner or some other dialog to
the user to let them know that you're doing some work **/
}
@Override
public void onPageFinished(WebView view, String url)
{
/** hide the feedback that was provided to the user **/
}
};
}
External Browser Interactions
It's important to note that there is only one WebChromeClient. Because of this you'll likely want to subclass WebChromeClient if you plan to provide many of these advanced features in your app. Here's an example of creating a WebChromeClient that can update the progress indicator of a Fragments Activity.
private WebChromeClient getWebChromeClient()
{
return new WebChromeClient()
{
public void onProgressChanged(WebView view, int progress)
{
if(getActivity() != null)
{
getActivity().setProgress(progress * 100);
}
}
};
}
For a more detailed example of integrating a basic web browser into your app, see the BrowserFragment in my open source RSS Reader Android app.
No comments:
Post a Comment