问题
I am trying to implement Visualization: Geomap in android Webview.
For Visualization:Geomap, I refer developers.google.com /chart/interactive/docs/gallery/geomap
Here I have implemented first example to show regions on map. In android webview when I touch on specific region it shows the popup with country name, as I touch outside region of map it shows the same popup.
ISSUE: In android webview , popup doesn’t disappear when I touch outside Google map. It should work similarly as on desktop web browser
DESKTOP VERSION:
I created demo.html file on desktop . Its running properly in web browser .
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["geomap"]});
google.setOnLoadCallback(drawMap);
function drawMap() {
var data = google.visualization.arrayToDataTable([
['Country', 'Popularity'],
['Germany', 200],
['United States', 300],
['Brazil', 400],
['Canada', 500],
['France', 600],
['RU', 700]
]);
var options = {};
options['dataMode'] = 'regions';
var container = document.getElementById('regions_div');
var geomap = new google.visualization.GeoMap(container);
geomap.draw(data, options);
};
</script>
</head>
<body>
<div id="regions_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
ANDROID VERSION:
DOWNLOAD APP
http://i62.tinypic.com/edb9w.jpg
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.widget.Toast;
public class WebActivity extends ActionBarActivity {
WebView webView;
StringBuilder build = new StringBuilder();
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web);
webView=(WebView)findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB)
webView.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
webView.setInitialScale(getScale());
webView.setWebChromeClient(new WebChromeClient());
build.append("['Germany', 200],");
build.append("['United States', 700],");
build.append("['Brazil', 300],");
build.append("['Canada', 400],");
build.append("['France', 500]");
drawMap();
//webView.loadUrl("http://www.stalwarttech.net/dummy/demo3.html");
}
void drawMap()
{
if(build.length() > 0)
{
String js = "<html><head>" +
"<script type='"+"text/javascript"+"' src='"+"https://www.google.com/jsapi"+"'></script>"+
"<script type='"+"text/javascript"+"'>" +
"google.load('"+"visualization"+"', '"+"1"+"', {packages:['"+"geochart"+"']});" +
"google.setOnLoadCallback(drawRegionsMap);" +
" function drawRegionsMap() {" +
" var data = google.visualization.arrayToDataTable([" +
"['Country', 'Popularity']," + build +
"]);" +
"var options = {colors: ['#CB96CE', '#871F7B']};" +
"var chart = new google.visualization.GeoChart(document.getElementById('regions_div'));" +
"chart.draw(data, options);" +
"}" +
"</script>" +
"</head>" +
"<body>" +
"<div id='"+"regions_div"+"' style='"+"width:100%; height: 100%;"+"'></div>" +
"</body>" +
"</html>";
Log.d("tag",js);
webView.loadDataWithBaseURL("file:///android_asset/", js, "text/html","UTF-8", null);
}
else
{
Toast.makeText(this, "No data found", Toast.LENGTH_LONG).show();
}
}
private int getScale(){
Display display=((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width=display.getWidth();
Double val=new Double(width)/new Double(800);
val=val*100d;
return val.intValue();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.web, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
回答1:
<html> <head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js">
</script>
<script type="text/javascript">
function loadGeoChart(mapsApiKey, dataList) {
google.charts.load('current', {
'packages': ['geochart'],
// Note: you will need to get a mapsApiKey for your project.
// See: https://developers.google.com/chart/interactive/docs/basic_load_libs#load-settings
'mapsApiKey': mapsApiKey
});
google.charts.setOnLoadCallback(function() {
drawRegionsMapAll(dataList)
});
}
function drawRegionsMapAll(datalist) {
var chart_data = [
['Country', 'Hits']
];
chart_data = chart_data.concat(datalist);
var data = google.visualization.arrayToDataTable(chart_data);
var options = {
colors: ['#81A9FF', '#2558C6']
};
var chart = new google.visualization.GeoChart(document.getElementById('regions_div'));
chart.draw(data, options);
}
function onLoad() {
Android.getMapData();
}
onLoad();
</script>
</head>
<body>
<div id="regions_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
Save the above geomap.html file in the assets folder.
In the Activity, load the html file in a webview, enabling the following Websettings.
WebSettings webSettings = mapweb_view.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDisplayZoomControls(false);
webSettings.setSupportZoom(true);
webSettings.setDefaultTextEncodingName("utf-8");
mapweb_view.addJavascriptInterface(new MapViewJSInterface(getContext(), this), "Android");
mapweb_view.loadUrl("file:///android_asset/geomap.html");
Android Code:
@JavascriptInterface
public void getMapData() {
getMapHitsAll();//custom method to load data to show on map
}
Call this method inorder to initialize the map and set data
getMapHitsAll() will return the 'mapkey' and required 'dataString' to be shown on geochart and then the javascript method will be invoked as follows:
mapweb_view.loadUrl("javascript:loadGeoChart('" + mapkey + "', " + dataString + ")");
回答2:
ALL PLATFORM SUPPORT
All what you need to do is just create ".html" file programmatically and store the html content into that file then open the same file in webview with absolute address of that file ... simple as that :)
here you go, out of the box
private void loadWorldMap() { try {
String htmlDocument = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" +
"<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><meta http-equiv=\"Content-Type\" content=\"text/html,width=device-width,user-scalable=yes; charset=windows-1252\">\n" +
" <script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>\n" +
" <script type=\"text/javascript\">\n" +
" google.load('visualization', '1', {'packages': ['geochart']});\n" +
" google.setOnLoadCallback(drawRegionsMap);\n" +
"\n" +
" function drawRegionsMap() {\n" +
" var data = google.visualization.arrayToDataTable([\n" +
" ['Country', ''],\n"
//add your city data buffer [List of countries] ;)
+ build +
" ]);\n" +
"\n" +
" var options = {};\n" +
"\t\toptions = { \n" +
" datalessRegionColor: '#29ABE2',\n" +
"\t\t\t\t backgroundColor: '#F3F3F3',\n" +
"\t\t\t\t\tcolorAxis: {colors: ['#0071BC']},\n" +
" keepAspectRatio: false, \n" +
" legend: false,\n" +
" tooltip: { textStyle: { color: '#0099CB', fontName: 'Arial', fontSize: '10'} }\n" +
" };\n" +
"\t\t\n" +
" var chart = new google.visualization.GeoChart(document.getElementById('chart_div'));\n" +
" chart.draw(data, options);\n" +
" };\n" +
" </script>\n" +
" </head>\n" +
" <body>\n" +
" <div id=\"chart_div\" style=\"width: 100%; height: 100%;\"><div style=\"position: relative;\"><div dir=\"ltr\" style=\"position: relative; width: 100%; height: 100%;\"><div style=\"position: absolute; left: 0px; top: 0px; width: 100%; height: 100%;\"></div></div></div></div>\n" +
" \n" +
"</body></html>";
// Creates a trace file in the primary external storage space of the
// current application.
// If the file does not exists, it is created.
File traceFile = new File((this).getCacheDir(), "TraceFile.html");
if (!traceFile.exists())
traceFile.createNewFile();
// Adds a line to the trace file
BufferedWriter writer = new BufferedWriter(new FileWriter(traceFile, false /*append*/));
writer.write(htmlDocument);
writer.close();
MediaScannerConnection.scanFile(getApplicationContext(),
new String[]{traceFile.toString()},
null,
null);
Log.d("file created", "Success.");
Log.d("absolute path ", traceFile.getAbsolutePath());
absoluteDir = traceFile.getAbsolutePath();
// Load world map
mapView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);
mapView.getSettings().setJavaScriptEnabled(true);
mapView.getSettings().setBuiltInZoomControls(false);
mapView.getSettings().setUseWideViewPort(true);
mapView.requestFocusFromTouch();
mapView.requestFocus(View.FOCUS_DOWN);
mapView.getSettings().setLoadWithOverviewMode(true);
//webView.setWebViewClient(new WebViewClient());
mapView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
llLoadingMap.setVisibility(View.VISIBLE);
if (progress == 100)
llLoadingMap.setVisibility(View.GONE);
}
});
mapView.loadUrl("file:///" + absoluteDir);
mapView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
int screenWidth = getWindowManager()
.getDefaultDisplay().getWidth();
mapView.setLayoutParams(new LinearLayout.LayoutParams(
screenWidth, LinearLayout.LayoutParams.MATCH_PARENT, 1f));
} catch (IOException e) {
Log.e("error file", "Unable to write to the TraceFile.html file.");
}
}
来源:https://stackoverflow.com/questions/27657116/unable-to-implement-visualizationgeomap-in-android-webview