问题
I am developing an application that uses WebView to display a webpage. The webpage contains a registration form and a "next" button. I want to know if it is possible to show Android toast message if the users presses next, but has failed to fill the input areas or the data does not meet the required criteria. I have the validation logic written, but I am not sure about Toasts, can someone point me in the right direction?
回答1:
You can solve your problem by implementing a simple JavaScript interface. Below is a simple sample.
assets/button_demo.xml
<html>
<head></head>
<body style="margin:0; padding:0;">
<style type="text/css">
#demo {
height: 100%;
width: 100%;
margin-left: auto;
margin-right: auto;
overflow: auto;
}
#demo a {
font-family: sans-serif;
font-size: 8pt;
width: 95%;
height: 35px;
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
padding: 5px;
margin: 1px;
border: 1px solid blue;
text-decoration: none;
color: blue;
word-wrap: break-word;
}
</style>
<script type="text/javascript">
function showToast(str){
Android.showToast(str);
}
</script>
<div id="demo">
<a href="javascript: showToast('test')">button</a>
</div>
</body>
</html>
activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/webView"
android:layout_centerVertical="true"/>
</RelativeLayout>
MainActivity.java
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import java.lang.ref.WeakReference;
public class MainActivity extends ActionBarActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.setWebViewClient(new MyWebClient());
webView.addJavascriptInterface(new WebInterface(MainActivity.this), "Android");
webView.loadUrl("file:///android_asset/button_demo.html");
}
private class MyWebClient extends WebViewClient {
/**
* It is a good idea to let proper web browsers handle URLs you don't know otherwise
* you could be putting your users to danger by injecting JavaScript interface
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//return super.shouldOverrideUrlLoading(view, url);
Uri uri;
try {
uri = Uri.parse(url);
} catch (NullPointerException e) {
// let Android deal with this
return true;
}
String host = uri.getHost(); //Host is null when user clicked on email, phone number, ...
if (host != null && host.equals("stackoverflow.com")) {
// This is my web site, so do not override; let my WebView load the page
return false;
}
else {
// Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs or anything else (email, phone number, ...)
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
@Override
public void onPageFinished(WebView view, String url) {
Log.d(TAG, "Page finished loading");
super.onPageFinished(view, url);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// No connection or HTTP error e.g. 404
Log.d(TAG, "Received webview error: " + errorCode + " - " + description + " ; " + failingUrl);
}
}
private final class WebInterface {
/**
* Caution: If you've set your targetSdkVersion to 17 or higher, you must
* add the @JavascriptInterface annotation to any method that you want
* available to your JavaScript (the method must also be public). If you do
* not provide the annotation, the method is not accessible by your web page
* when running on Android 4.2 or higher.
*/
private WeakReference<Activity> mContextRef;
private Toast toast;
public WebInterface(Activity context) {
this.mContextRef = new WeakReference<Activity>(context);
}
@JavascriptInterface
public void showToast(final String toastMsg) {
if (TextUtils.isEmpty(toastMsg) || mContextRef.get() == null) {
return;
}
// JavaScript doesn't run on the UI thread, make sure you do anything UI related like this
// You don't need this for the Toast, but otherwise it's a good idea
mContextRef.get().runOnUiThread(new Runnable() {
@Override
public void run() {
if (toast != null) {
toast.cancel();
}
toast = Toast.makeText(mContextRef.get(), toastMsg, Toast.LENGTH_SHORT);
toast.show();
}
});
}
}
}
来源:https://stackoverflow.com/questions/29779954/android-webview-showtoast-onbuttonclick