Introduction to this section
This section brings you a control for displaying web pages in Android: WebView (web view).
Now there are two directions of Android application layer development: client development and HTML5 mobile development!
The so-called HTML5 side is: HTML5 + CSS + JS to build a web version of the application, and the intermediate medium is this WebView, and the web and the web side can interact through JS, for example, the web page reads the mobile phone contacts, calls Mobile phone-related APIs, etc.!
And compared to ordinary client development, the HTML5 mobile terminal has an advantage: it can be laid out with percentages, and if there is any major change in the HTML5 terminal, we don't have to re-download the APP like the client, and then overwrite the installation, we just Need to modify the next page! And the client...it's terrible, of course, HTML5 also has shortcomings, that is, performance problems, data accumulation, power consumption problems, and splash screens, etc...
In addition, for this kind of cross-platform, we can use other third-party rapid development frameworks, such as PhoneGap. By the way, there are many websites on the Internet that generate APPs with one click. Users drag and drop, set pictures and other simple operations. An application can be generated, most of which are done with HTML5! There is a template, you can set it up directly, you know~ Okay, without further ado, let's start this section!
1. What is WebView?
Answer: Android has a high-performance browser with built-in webkit kernel, and WebView is a control encapsulated on this basis. WebView literally translates web view. We can simply regard it as a browser control that can be nested on the interface !
2. Related methods
First go to the official document: WebView does not intend to talk about attributes one by one, write which one is used, and consult the documentation by yourself! In addition to direct WebView, we can also add your own behavior, you can customize the following classes:
WebChromeClient : assists WebView to process Javascript dialog boxes, website icons, website titles, loading progress, etc.! For example the following:
method | effect |
---|---|
onJsAlert(WebView view,String url,String message,JsResult result) | Handle the Alert dialog box in Js |
onJsConfirm(WebView view,String url,String message,JsResult result) | Handle the Confirm dialog box in Js |
onJsPrompt(WebView view,String url,String message,String defaultValue,JsPromptResult result) | Handle the Prompt dialog box in Js |
onProgressChanged(WebView view,int newProgress) | Called when the loading progress bar changes |
onReceivedIcon(WebView view, Bitmap icon) | Get the icon of the web page |
onReceivedTitle(WebView view, String title) | Get the title of the page |
WebViewClient : Assist WebView to handle various notification and request events! For example, the following methods:
method | effect |
---|---|
onPageStared(WebView view,String url) | Notify the main program web page to start loading |
onPageFinished(WebView view,String url,Bitmap favicon) | Notify the main program that the webpage is loaded |
doUpdateVisitedHistory(WebView view,String url,boolean isReload) | update history |
onLoadResource(WebView view,String url) | Notify the main program that WebView is about to load the resource of the specified url |
onScaleChanged(WebView view,float oldScale,float newScale) | Called when the zoom of the ViewView changes |
shouldOverrideKeyEvent(WebView view,KeyEvent event) | Control whether the webView processes the button time, if it returns true, the WebView does not process it, and returns false to process it |
shouldOverrideUrlLoading(WebView view,String url) | Controls the processing of the newly loaded Url, returns true, indicating that the main program does not process WebView, and returns false means that WebView will process it |
onReceivedError(WebView view,int errorCode,String description,String failingUrl) | Called when an unrecoverable error message is encountered |
WebSettings : WebView-related configuration settings, such as setJavaScriptEnabled() setting whether to allow JS script execution Some methods are as follows:
method | effect |
---|---|
getSettings() | Returns a WebSettings object to control the property settings of WebView |
loadUrl(String url) | Load the specified Url |
loadData(String data,String mimeType,String encoding) | Load the specified Data into WebView. Use "data:" as the tag header, this method cannot load network data. Among them, mimeType is the data type such as: textml, image/jpeg. encoding is the character encoding method |
loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) | More powerful than loadData above |
setWebViewClient(WebViewClient client) | Specify a WebViewClient object for WebView. WebViewClient can assist WebView to handle various notifications, requests and other events. |
setWebChromeClient(WebChromeClient client) | Specify a WebChromeClient object for WebView. WebChromeClient is specially used to assist WebView in handling js dialog boxes, website titles, website icons, loading progress bars, etc. |
Here it is important to distinguish the difference between the three load methods:
loadUrl (): directly display the content of the webpage (display network pictures separately), and generally there will be no garbled characters. loadData (data, "text/html", "UTF-8"): used to load data in URI format, cannot load content through the network, cannot load pictures, and often encounter problems of garbled characters, we know String type The data is mainly encoded in Unicode, and WebView generally uses UTF-8 encoding to save resources. Although we wrote above, we still need to set it for webView: webview.getSettings().setDefaultTextEncodingName("UTF -8"); loadDataWithBaseURL (baseUrl, string, "text/html", "utf-8", null): An enhanced class of the loadData class, which can load pictures, baseUrl is the path of the pictures you store, and you only need to set utf-8 here Can solve the garbled problem!
Here is just a list of some attributes, others need to consult the official documents:
3. Explanation of some common requirements
Requirement 1: Load web pages according to URL
1) Load a WebView directly on the Activity
Running effect diagram :
Implementation code :
public class MainActivity extends AppCompatActivity { private WebView webView; private long exitTime = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = new WebView(this ); webView.setWebViewClient(new WebViewClient() { //Set the new webpage opened by clicking on webView to display on the current interface instead of jumping to the new browser @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl (url); return true; } }); webView.getSettings().setJavaScriptEnabled(true); //Set WebView properties, run and execute js script webView.loadUrl("http://www.baidu.com/"); //Call the loadUrl method to add links to WebView setContentView( webView); //Call the setContentView provided by Activity to display the webView } //We need to rewrite the time of the back button, when the user clicks the back button: //1.webView.canGoBack() to determine whether the webpage can go back, you can Then goback() //2. If you can’t click twice in a row to exit the App, otherwise a Toast will pop up @Override public void onBackPressed() { if (webView.canGoBack()) { webView.goBack(); } else { if ( (System. currentTimeMillis() - exitTime) > 2000) { Toast.makeText(getApplicationContext(), "Press again to exit the program", Toast. LENGTH_SHORT). show(); exitTime = System.currentTimeMillis(); } else { super.onBackPressed(); } } } }
2) Set WebView in the layout code
I believe everyone has seen a lot of news apps or portal information apps. His structure may be like this:
In the upper left corner, there is a button to click to close the current Activity. In the middle is the title of the news. On the right is a refresh button. In the lower right corner, there may be such a floating button. When we slide beyond the screen width, it will be displayed. When the user clicks Will scroll back to the top of the page! Let's implement it 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() { //这里设置获取到的网站title @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); txt_title.setText(title); } }); wView.setWebViewClient(new WebViewClient() { //Open a new link in 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 program", Toast.LENGTH_SHORT).show(); exitTime = System.currentTimeMillis(); } else { finish(); } } } }
Questions and Answers :
I believe careful friends can see that after we return to the page loaded at the beginning, we press the back button. After pressing it many times, we still haven’t exited the current APP. Later, we still need to manually click the back button and call the finish method to close the current Activity? Why is this? Obviously Baidu is already the first page?
Answer: In fact, the reason for this is: the URL redirection problem caused, in fact, when we visit Baidu:
Although we loaded www.baidu.com, Baidu made a redirection and jumped to the mobile version of Baidu’s website: In other words, your actual process is: www.baidu.com -> mobile version of Baidu’s website -> open other Link!
We see that our above shouldOverrideUrlLoading() method is written like this:
view.loadUrl(url); return true; We know that the user clicks the back button once, then the webview will call the goback method (), we set the above three sites as A, B, and C, and click back at C Back, C -> B is fine, and then click B -> A, this time the problem comes, although B came to A, but because of the redirection, it jumps to B again, and so on and on... That's why click back The reason why the back button does not launch the WebView, the solution: hand speed, double-click the back button continuously before the webpage is loaded in the webview, the hand speed must be fast enough, haha! Just kidding, to solve this problem, we only need to delete the stuff in shouldOverrideUrlLoading, and then write return false ; that's it! If you don’t believe it’s a redirection, you can try modifying the URL yourself~
Requirement 2: Listening to WebView scrolling events
We all know that setOnScrollChangedListener is generally used to monitor scrolling events. Unfortunately, WebView does not provide us with such a method, but we can rewrite WebView and override a method inside: protected void onScrollChanged(final int l, final int t, final int oldl,final int oldt){} Then provide an interface to the outside world, 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 onScrollChangedC allback) { mOnScrollChangedCallback = onScrollChangedCallback; } public static interface OnScrollChangedCallback { // dx and dy represents the offset on the x-axis and y-axis, you can also expose the four parameters l, t, oldl, oldt by yourself 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() { //在webview里打开新链接 @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); public void onClick(View v) { return true; } }); //For example, make a simple judgment here, when the page scrolls, display the Button 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 btn_icon .setVisibility(View.GONE); } wView.setScrollY(0); }); } @Override public void onBackPressed() { if (wView.canGoBack()) { wView.goBack(); } else { if ((System.currentTimeMillis() - exitTime) > 2000 ) { Toast.makeText(getApplicationContext(), "Press again to exit the program", Toast.LENGTH_SHORT).show(); exitTime = System.currentTimeMillis(); } else { finish(); } } } }
Running effect diagram :
When the webpage starts to scroll, there will be a Haha button, we click the Haha button to go back to the top! Then the Haha button will hide~
Requirement 3: Problems with scroll bars
The attributes you might use are as follows:
- setHorizontalScrollBarEnabled(false);//Horizontal does not display
- setVerticalScrollBarEnabled(false); //Do not display vertically
- setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);//The scroll bar is displayed inside the WebView
- setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY)//The scroll bar is displayed outside the WebView
Requirement 4: Set scaling and adaptive screen
According to our general habit of opening webpages, we like to zoom the webpage with two fingers for places that cannot be seen clearly, while WebView needs us to manually set whether this supports zooming or not!
Just add the following code:
WebSettings settings = wView.getSettings(); settings.setUseWideViewPort(true);//Set viewport support settings.setLoadWithOverviewMode(true); //Adaptive screen settings.setBuiltInZoomControls(true); settings.setDisplayZoomControls(false); settings. setSupportZoom(true);//Set support zoom
After using the above code, entering the page will look like this:
When we zoom, there is a disgusting problem, which is a very common zoom control, we definitely don't want it, then add the following code to hide the zoom control!
settings.setDisplayZoomControls(false);
We can also set the initial zoom ratio by ourselves, just for webView:
wView.setInitialScale(25);//25%, the minimum zoom level
Hey, the above is that the entire webpage is scaled, but maybe sometimes we just need to scale the font, so we can do this:
settings.setTextZoom(int);
You can also directly pass:
settings.setTextSize(TextSize.LARGER);
to set the size.
Android comes with five optional font size values: SMALLEST(50%), SMALLER(75%), NORMAL(100%), LARGER(150%), LARGEST(200%).
Requirement 5. Get the cookie data of WebView
We all know that a cookie is actually just a string representing the unique identifier of the user. The scenario is generally: After the user enters the account password and clicks to log in, the user needs to take this cookie to access the related services provided by the server! We can write the cookie acquisition into the onPageFinsihed method, which can be simply written like this:
@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. Set the cookie data of WebView
Hey, we have obtained cookies above or through other means, how do we set cookies for WebView? We can add the following code where we need to set cookies:
CookieSyncManager.createInstance(MainActivity.this); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie(true); cookieManager.setCookie(url, cookies); //cookies is the cookie string to be set CookieSyncManager.getInstance(). sync();
By the way, the above code needs to be written before loadUrl(), and if the cookie is set, try not to make other settings, or it may be invalid. It is recommended to write the cookie setting at the end of the webView related settings~before loadUrl()!