7.5.1 Basic Usage of WebView (Web View)
Category Android Basic Introduction Tutorial
Introduction to This Section
>
This section introduces WebView, a web display control in Android.
Currently, there are two main directions in Android application development: client-side and HTML5 mobile development.
HTML5 mobile development involves building a web-based application using HTML5, CSS, and JavaScript, with WebView serving as the intermediary. Web and web pages can interact via JavaScript, such as reading phone contacts or invoking mobile APIs.
Compared to traditional client-side development, HTML5 mobile development has an advantage: it allows layout in percentages, and if there are major changes in the HTML5 part, we don't need to download a new app and reinstall it; we just need to modify the web page. Client-side development... not so great. However, HTML5 also has its drawbacks, such as performance issues, data accumulation, battery drain, and screen flickering.
Additionally, for cross-platform development, we can use third-party rapid development frameworks like PhoneGap. There are also many websites online that allow users to drag and drop, set images, and perform simple operations to generate an app, mostly using HTML5. Templates are available, just plug and play.
Now, without further ado, let's get started with this section!
1. What is WebView?
>
Answer: WebView is a high-performance browser built on the WebKit kernel, encapsulated as a control. It can be simply regarded as a browser component that can be embedded into the interface.
2. Related Methods
>
First, refer to the official documentation: WebView. I won't go through each attribute one by one; I'll cover them as needed, and you can refer to the documentation for others.
In addition to the basic WebView, you can also add your own behaviors by customizing the following classes:
WebChromeClient: Assists WebView in handling JavaScript dialogs, website icons, titles, loading progress, etc.
Method | Function |
---|---|
onJsAlert(WebView view, String url, String message, JsResult result) | Handle Alert dialogs in JavaScript |
onJsConfirm(WebView view, String url, String message, JsResult result) | Handle Confirm dialogs in JavaScript |
onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) | Handle Prompt dialogs in JavaScript |
onProgressChanged(WebView view, int newProgress) | Called when the loading progress changes |
onReceivedIcon(WebView view, Bitmap icon) | Get the icon of the web page |
onReceivedTitle(WebView view, String title) | Get the title of the web page |
WebViewClient: Assists WebView in handling various notifications and request events.
Method | Function |
---|---|
onPageStarted(WebView view, String url) | Notify the main program that the web page starts loading |
onPageFinished(WebView view, String url, Bitmap favicon) | Notify the main program that the web page has finished loading |
doUpdateVisitedHistory(WebView view, String url, boolean isReload) | Update the history |
onLoadResource(WebView view, String url) | Notify the main program that WebView is about to load the specified resource |
onScaleChanged(WebView view, float oldScale, float newScale) | Called when the scale of WebView changes |
shouldOverrideKeyEvent(WebView view, KeyEvent event) | Control whether WebView handles key events; return true to prevent handling, false to handle |
shouldOverrideUrlLoading(WebView view, String url) | Control how new URLs are handled; return true to let the main program handle it, false to let WebView handle it |
onReceivedError(WebView view, int errorCode, String description, String failingUrl) | Called when an unrecoverable error occurs |
WebSettings: Settings for WebView configuration, such as setJavaScriptEnabled() to enable or disable JavaScript.
Method | Function |
---|---|
getSettings() | Return a WebSettings object to control WebView attribute settings |
loadUrl(String url) | Load the specified URL |
loadData(String data, String mimeType, String encoding) | Load specified data into WebView using "data:" as the header; cannot load network data, and mimeType specifies the data type like text/html, image/jpeg; encoding specifies the character encoding |
loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) | A more powerful version of loadData |
setWebViewClient(WebViewClient client) | Specify a WebViewClient object for WebView to handle various notifications and request events |
setWebChromeClient(WebChromeClient client) | Specify a WebChromeClient object for WebView to handle JavaScript dialogs, website titles, icons, loading progress, etc. |
It's important to distinguish between the three load methods:
>
loadUrl(): Directly displays web content (including standalone images) and usually does not have encoding issues. loadData(data, "text/html", "UTF-8"): Used to load URI-formatted data; cannot load images or network content and often encounters encoding issues. We know that String data is primarily Unicode-encoded, while WebView typically uses UTF-8 to save resources. Even if we set it as above, we also need to set: webview.getSettings().setDefaultTextEncodingName("UTF-8"). loadDataWithBaseURL(baseUrl, string, "text/html", "utf-8", null): An enhanced version of loadData that can load images, with baseUrl being the stored image path, and setting utf-8 here can resolve encoding issues.
This only lists some attributes; others need to be checked in the official documentation:
3. Explanation of Some Common Requirements
Requirement 1: Load a Web Page Based on URL
1) Directly Load a WebView in an Activity
Screenshot of the Running Effect:
exitTime = System.currentTimeMillis();
} else {
super.onBackPressed();
}
}
}
}
2) Setting up WebView in Layout Code
I believe many of you have seen many news or portal information apps. Their structure might look like this:
A button in the top left corner to close the current activity, a news title in the middle, a refresh button on the right, and a floating button in the bottom right corner that appears when you scroll beyond the screen width and scrolls back to the top of the webpage when clicked. Let's implement this simply!
Running Effect Diagram:
Implementation Code:
MainActivity.java:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_back;
private TextView txt_title;
private Button btn_top;
private Button btn_refresh;
private WebView wView;
private long exitTime = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
}
private void bindViews() {
btn_back = (Button) findViewById(R.id.btn_back);
txt_title = (TextView) findViewById(R.id.txt_title);
btn_top = (Button) findViewById(R.id.btn_top);
btn_refresh = (Button) findViewById(R.id.btn_refresh);
wView = (WebView) findViewById(R.id.wView);
btn_back.setOnClickListener(this);
btn_refresh.setOnClickListener(this);
btn_top.setOnClickListener(this);
wView.loadUrl("http://www.baidu.com");
wView.setWebChromeClient(new WebChromeClient() {
// Set the website title here
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
txt_title.setText(title);
}
});
wView.setWebViewClient(new WebViewClient() {
// Open new links in the webview
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_back:
finish(); // Close the current Activity
break;
case R.id.btn_refresh:
wView.reload(); // Refresh the current page
break;
case R.id.btn_top:
wView.setScrollY(0); // Scroll to the top
break;
}
}
@Override
public void onBackPressed() {
if (wView.canGoBack()) {
wView.goBack();
} else {
if ((System.currentTimeMillis() - exitTime) > 2000) {
Toast.makeText(getApplicationContext(), "Press again to exit the app",
Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
finish();
}
}
}
}
Question and Answer:
Some attentive friends may notice that after returning to the initial page, pressing the back key multiple times still does not exit the current app. Later, we have to manually press the back key and call the finish method to close the current activity. Why is this happening? Isn't Baidu the first page?
Answer: The reason for this is the redirection issue. When we visit Baidu, even though we load www.baidu.com, Baidu redirects to the mobile version of the Baidu search page, i.e., the actual process is: www.baidu.com -> Mobile Baidu Search -> Open other links.
We see that the shouldOverrideUrlLoading() method is written like this:
view.loadUrl(url); return true; We know that every time the user presses the back key, the webview calls the goBack method(). If we consider the three sites as A, B, and C, when we press back at C, C -> B is fine, and then B -> A. At this point, the problem arises. Although B comes to A, due to redirection, it jumps back to B, repeating this process... This is why pressing the back key does not exit the WebView. To solve this problem, you can quickly double-tap the back key before the webview finishes loading the webpage, but that's just a joke. To actually solve this problem, simply delete the content in shouldOverrideUrlLoading and write return false; instead. If you don't believe it's a redirection issue, you can try modifying the URL yourself.
Requirement 2: Listening to WebView Scroll Events
We know that listening to scroll events is usually done by setting setOnScrollChangedListener, but unfortunately, WebView does not provide us with such a method. However, we can override WebView and cover a method: protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt){} Then provide an interface externally. The sample code is as follows:
MyWebViewDemo.java:
/**
* Created by Jay on 2015/9/11 0011.
*/
public class MyWebView extends WebView {
private OnScrollChangedCallback mOnScrollChangedCallback;
public MyWebView(Context context) {
super(context);
}
public MyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mOnScrollChangedCallback != null) {
mOnScrollChangedCallback.onScroll(l - oldl, t - oldt);
}
}
public OnScrollChangedCallback getOnScrollChangedCallback() {
return mOnScrollChangedCallback;
}
public void setOnScrollChangedCallback(
final OnScrollChangedCallback onScrollChangedCallback) {
mOnScrollChangedCallback = onScrollChangedCallback;
}
public static interface OnScrollChangedCallback {
// dx and dy represent the offset on the x-axis and y-axis, respectively. You can also expose the l, t, oldl, oldt parameters
public void onScroll(int dx, int dy);
}
}
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private MyWebView wView;
private Button btn_icon;
private long exitTime = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_icon = (Button) findViewById(R.id.btn_icon);
wView = (MyWebView) findViewById(R.id.wView);
wView.loadUrl("http://www.hao123.com");
wView.setWebViewClient(new WebViewClient() {
// Open new links in the webview
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
// For example, make a simple judgment, show the Button when the page scrolls
wView.setOnScrollChangedCallback(new MyWebView.OnScrollChangedCallback() {
@Override
public void onScroll(int dx, int dy) {
if (dy > 0) {
btn_icon.setVisibility(View.VISIBLE);
} else {
btn_icon.setVisibility(View.GONE);
}
}
});
btn_icon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wView.setScrollY(0);
btn_icon.setVisibility(View.GONE);
}
});
@Override
public void onBackPressed() {
if (wView.canGoBack()) {
wView.goBack();
} else {
if ((System.currentTimeMillis() - exitTime) > 2000) {
Toast.makeText(getApplicationContext(), "Press back again to exit the app",
Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
finish();
}
}
}
Running Effect Diagram:
When the web page starts scrolling, a button labeled "hehe" will appear. Clicking the "hehe" button will take you back to the top! Then the "hehe" button will hide.
Requirement 3: Scrollbar Issues
You might use the following properties:
- setHorizontalScrollBarEnabled(false); // Hide horizontal scrollbar
- setVerticalScrollBarEnabled(false); // Hide vertical scrollbar
- setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); // Scrollbar inside WebView
- setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); // Scrollbar outside WebView
Requirement 4: Setting Zoom and Screen Adaptation
To enable zooming with two fingers, you need to manually set this in WebView. Add the following code:
WebSettings settings = wView.getSettings();
settings.setUseWideViewPort(true); // Support viewport
settings.setLoadWithOverviewMode(true); // Adapt to screen
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(false);
settings.setSupportZoom(true); // Support zoom
After adding the above code, the page will look like this:
When zooming, a common zoom control appears, which we don't want. Adding the following line will hide the zoom control:
settings.setDisplayZoomControls(false);
You can also set the initial zoom scale for the WebView:
wView.setInitialScale(25); // 25% is the minimum zoom level
If you only want to zoom the text, you can do this:
settings.setTextZoom(int);
Or directly set the size via:
settings.setTextSize(TextSize.LARGER);
Android provides five optional font size values: SMALLEST(50%), SMALLER(75%), NORMAL(100%), LARGER(150%), LARGEST(200%).
Requirement 5: Getting WebView's Cookie Data
Cookie is a string that uniquely identifies a user. Typically, after entering the account and password, the user needs to use this Cookie to access the services provided by the server. You can write the code to get the cookie in the onPageFinished method:
@Override
public void onPageFinished(WebView view, String url) {
CookieManager cookieManager = CookieManager.getInstance();
String CookieStr = cookieManager.getCookie(url);
Log.e("HEHE", "Cookies = " + CookieStr);
super.onPageFinished(view, url);
}
Requirement 6: Setting WebView's Cookie Data
To set a Cookie for the WebView, add the following code where needed:
CookieSyncManager.createInstance(MainActivity.this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.setCookie(url, cookies); // cookies is the string to be set
CookieSyncManager.getInstance().sync();
Make sure this code is added before loadUrl() and avoid making other settings after setting the cookie to prevent it from becoming ineffective. It's recommended to place the cookie setting code at the end of the WebView settings, just before loadUrl().
Sample Code Downloads:
WebViewDemo1: Download WebViewDemo1.zip
WebViewDemo2: Download WebViewDemo2.zip
Summary:
This section introduced the basic usage of WebView, including loading web pages, setting zoom, text zoom, screen adaptation, and getting and setting cookies. There are various other requirements in daily development, but due to space limitations, only these are covered. If you have ideas, feel free to comment. In the next section, we will learn how HTML5 can interact with WebView through JavaScript to obtain relevant mobile data. Stay tuned!
-1.0 Android Basic Introduction Tutorial
-1.0.1 2015 Latest Android Basic Introduction Tutorial Table of Contents
-1.1 Background and System Architecture Analysis
-1.2 Development Environment Setup
-1.2.1 Developing Android APP with Eclipse + ADT + SDK
-1.2.2 Developing Android APP with Android Studio
-1.3 Solving SDK Update Issues
-1.4 Genymotion Emulator Installation
-1.5.1 Git Tutorial for Basic Local Repository Operations
-1.5.2 Git: Setting Up a Remote Repository on GitHub
-1.6 How to Play with the 9-Image
-1.7 Interface Prototype Design
-1.8 Project Source Analysis (Various Files, Resource Access)
-1.9 Android Program Signing and Packaging
-1.11 Decompiling APK to Get Code & Resources
-2.1 Concepts of View and ViewGroup ```
- 2.2.1 LinearLayout (Linear Layout)
- 2.2.2 RelativeLayout (Relative Layout)
- 2.2.3 TableLayout (Table Layout)
- 2.2.4 FrameLayout (Frame Layout)
- 2.2.5 GridLayout (Grid Layout)
- 2.2.6 AbsoluteLayout (Absolute Layout)
- 2.3.1 TextView (Text View) Detailed Explanation
- 2.3.2 EditText (Input Box) Detailed Explanation
- 2.3.3 Button (Button) and ImageButton (Image Button)
- 2.3.4 ImageView (Image View)
- 2.3.5 RadioButton (Radio Button) & Checkbox (Checkbox)
- 2.3.6 Toggle Button and Switch
- 2.3.7 ProgressBar (Progress Bar)
- 2.3.8 SeekBar (Seek Bar)
- 2.3.9 RatingBar (Rating Bar)
- 2.4.1 ScrollView (Scroll View)
- 2.4.2 Date & Time Components (Part 1)
- 2.4.3 Date & Time Components (Part 2)
- 2.4.4 Adapter Basics
- 2.4.5 Simple Usage of ListView
- 2.4.6 Optimization of BaseAdapter
- 2.4.7 Focus Issues with ListView
- 2.4.8 Solving Checkbox Misalignment in ListView
- 2.4.9 Data Update Issues in ListView
- 2.5.0 Building a Reusable Custom BaseAdapter
- 2.5.1 Implementation of Multi-Layout ListView Items
- 2.5.2 Basic Usage of GridView (Grid View)
- 2.5.3 Basic Usage of Spinner (Dropdown List)
- 2.5.4 Basic Usage of AutoCompleteTextView (Auto-Complete Text View)
- 2.5.5 Basic Usage of ExpandableListView (Expandable List)
- 2.5.6 Basic Usage of ViewFlipper (Flip View)
- 2.5.7 Basic Usage of Toast
- 2.5.8 Detailed Explanation of Notification (Status Bar Notification)
- 2.5.9 Detailed Explanation of AlertDialog (Dialog Box)
- 2.6.0 Basic Usage of Other Common Dialogs
- 2.6.1 Basic Usage of PopupWindow (Floating Window)
- 2.6.2 Menu (Menu)
- 2.6.3 Simple Usage of ViewPager
- 2.6.4 Simple Usage of DrawerLayout (Official Side Slider Menu)
- 3.1.1 Event Handling Mechanism Based on Listeners
- 3.2 Event Handling Mechanism Based on Callbacks
- 3.3 Analysis of Handler Message Passing Mechanism
- 3.4 TouchListener vs OnTouchEvent + Multi-Touch
- 3.5 Listening for Content Changes in EditText
- 3.6 Responding to System Setting Events (Configuration Class)
- 3.7 AsyncTask Asynchronous Tasks
- 3.8 Gestures (Gestures)
- 4.1.1 Activity Beginner
- 4.1.2 Activity Intermediate
- 4.1.3 Activity Advanced
- 4.2.1 Service Beginner
- 4.2.2 Service Intermediate
- 4.2.3 Service Advanced
- 4.3.1 BroadcastReceiver Beginner
- 4.3.2 BroadcastReceiver Intermediate
- 4.4.1 ContentProvider Beginner
- 4.4.2 ContentProvider Intermediate - Document Provider
- 4.5.1 Basic Usage of Intent
- 4.5.2 Passing Complex Data with Intent
- 5.1 Fragment Basic Overview
- 5.2.1 Fragment Example - Bottom Navigation Bar Implementation (Method 1)
- 5.2.2 Fragment Example - Bottom Navigation Bar Implementation (Method 2)
- 5.2.3 Fragment Example - Bottom Navigation Bar Implementation (Method 3)
- 5.2.4 Fragment Example - Bottom Navigation Bar + ViewPager Page Sliding
- 5.2.5 Fragment Example - Simple Implementation of News (Shopping) App List Fragment
- 6.1 Data Storage and Access - File Storage and Reading
- 6.2 Data Storage and Access - SharedPreferences for Saving User Preferences
- 6.3.1 Data Storage and Access - Introduction to SQLite Database
- 6.3.2 Data Storage and Access - Further Exploration of SQLite Database
- 7.1.1 Android Network Programming Overview and HTTP Protocol Study
- 7.1.2 Study of Android HTTP Request Headers and Response Headers
- 7.1.3 Android HTTP Request Method: HttpURLConnection
- 7.1.4 Android HTTP Request Method: HttpClient
- 7.2.1 Android XML Data Parsing
- 7.2.2 Android JSON Data Parsing
- 7.3.1 Android File Upload
- 7.3.2 Android File Download (1)
- 7.3.3 Android File Download (2)
- 7.4 Android Calling WebService
7.5.1 Basic Usage of WebView(Web View)
7.5.3 Important Considerations for WebView after Android 4.4
8.3.4 Paint API — Xfermode and PorterDuff Detailed Explanation (Part 1)
8.3.5 Paint API — Xfermode and PorterDuff Detailed Explanation (Part 2)
8.3.6 Paint API — Xfermode and PorterDuff Detailed Explanation (Part 3)
8.3.7 Paint API — Xfermode and PorterDuff Detailed Explanation (Part 4)
8.3.8 Paint API — Xfermode and PorterDuff Detailed Explanation (Part 5)
8.3.14 Paint Enumeration/Constants and ShadowLayer Shadow Effect
8.3.17 Detailed Explanation of Canvas API (Part 2) Clip Methods Collection
8.3.18 Detailed Explanation of Canvas API (Part 3) Matrix and drawBitmapMesh
8.4.3 Property Animation in Android Animations Collection - First Encounter
8.4.4 Property Animation in Android Animations Collection - Second Encounter
11.0 Completion of the 2015 Latest Android Basic Introduction Tutorial
12.1 Android Practice: DrySister App (First Edition) — Project Setup and Simple Implementation
12.4 DrySister App (First Edition) — Adding Data Caching (Introducing SQLite)
12.5 DrySister App (First Edition) — Code Review, Adjustment, and Logging Class Writing
12.6 DrySister App (First Edition) — Icon Creation, Obfuscation, Signing, APK Slimming, App Release
WeChat Subscription
Please note that the translations provided are for the titles and descriptions of the topics and do not include the content of the linked pages.