需要用Android做报表,懒习惯了,从网上下个现成Web控件(无穷尽量,选中了Chart.js,又小又漂亮)的直接结合到android里,方便。
1. 下载Chart.js
Chart.js 下载地址
2. 新建Android项目
将下载的Chart.js-master解压后放到assets/web里。
3. 代码结构
3.1 入口Activity MainActivity
package com.zf.chartjs;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import com.zf.util.chart.ChartAction;
import com.zf.util.chart.ChartEntity;
import com.zf.util.web.WebViewUtil;
public class MainActivity extends FragmentActivity {
private static final String MAIN_BAR_ADDR = "file:///android_asset/web/Chart.js-master/samples/bar.html";
private static final String MAIN_DOUGHNUT_ADDR = "file:///android_asset/web/Chart.js-master/samples/doughnut.html";
private static final String MAIN_LINE_ADDR = "file:///android_asset/web/Chart.js-master/samples/line.html";
private static final String MAIN_PIE_ADDR = "file:///android_asset/web/Chart.js-master/samples/pie.html";
private static final String MAIN_POLAR_AREA_ADDR = "file:///android_asset/web/Chart.js-master/samples/polarArea.html";
private static final String MAIN_RADAR_ADDR = "file:///android_asset/web/Chart.js-master/samples/radar.html";
private static final String MAIN_SIXUP_ADDR = "file:///android_asset/web/Chart.js-master/samples/sixup.html";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container,
new PlaceholderFragment()).commit();
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_main, container, false);
WebView bar = (WebView) rootView
.findViewById(R.id.bar);
/* FIXME 如果信息是从网上或者数据库获得的,记得要用异步方法去调用 */
initDatas(bar);
new WebViewUtil().initWebview(bar, MAIN_BAR_ADDR);
WebView doughnut = (WebView) rootView
.findViewById(R.id.bar);
/* FIXME 如果信息是从网上或者数据库获得的,记得要用异步方法去调用 */
initDatas(doughnut);
new WebViewUtil().initWebview(doughnut,
MAIN_DOUGHNUT_ADDR);
WebView line = (WebView) rootView
.findViewById(R.id.line);
/* FIXME 如果信息是从网上或者数据库获得的,记得要用异步方法去调用 */
initDatas(line);
new WebViewUtil().initWebview(line, MAIN_LINE_ADDR);
WebView pie = (WebView) rootView
.findViewById(R.id.pie);
/* FIXME 如果信息是从网上或者数据库获得的,记得要用异步方法去调用 */
initDatas(pie);
new WebViewUtil().initWebview(pie, MAIN_PIE_ADDR);
WebView polarArea = (WebView) rootView
.findViewById(R.id.polarArea);
/* FIXME 如果信息是从网上或者数据库获得的,记得要用异步方法去调用 */
initDatas(polarArea);
new WebViewUtil().initWebview(polarArea,
MAIN_POLAR_AREA_ADDR);
WebView radar = (WebView) rootView
.findViewById(R.id.radar);
/* FIXME 如果信息是从网上或者数据库获得的,记得要用异步方法去调用 */
initDatas(radar);
new WebViewUtil().initWebview(radar, MAIN_RADAR_ADDR);
WebView sixup = (WebView) rootView
.findViewById(R.id.sixup);
/* FIXME 如果信息是从网上或者数据库获得的,记得要用异步方法去调用 */
initDatas(sixup);
new WebViewUtil().initWebview(sixup, MAIN_SIXUP_ADDR);
return rootView;
}
/**
* 初始化并为页面加载数据
*
* @author 曾凡
* @param webView
* @time 2014年5月16日 下午2:18:15
*/
private void initDatas(WebView webView) {
/* FIXME 以下为测试数据 */
ChartEntity progress = new ChartEntity();
ChartAction action = new ChartAction(getActivity(),
progress);
/* 向js发送配置信息 */
action.initDatas();
/* 返回值 */
webView.addJavascriptInterface(action, "action");
}
}
}
3.2 WebView工具类 WebViewUtil
package com.zf.util.web;
import android.graphics.Bitmap;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.webkit.ConsoleMessage;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.zf.util.Ln;
/**
* WebView的工具类
*
* @author 曾凡
* @time 2014年5月16日 上午10:48:32
*/
public class WebViewUtil {
private WebView mWebView = null;
/**
* 是否在web链接中启动新的Activity
*/
private boolean startNewActivity = false;
/**
* 是否启动内部监听back按钮
*/
private boolean enableBack = false;
/**
* 用户必须初始化类时必须调用,可以放到onCreate方法里去执行
*
* @author 曾凡
* @param contentViewId
* layout
* @param webViewId
* WebView的ID
* @param loadUrl
* 网页的地址(网络/本地)
* @time 2014年5月16日 上午11:03:03
*/
public void initWebview(WebView webView, String loadUrl) {
this.mWebView = webView;
WebSettings set = mWebView.getSettings();
/* 启动js */
set.setJavaScriptEnabled(true);
/* 支持缩放 */
set.setSupportZoom(true);
set.supportMultipleWindows();
if (!isEnableBack()) {
mWebView.setOnKeyListener(new MainWebViewOnKeyListener());
}
if (!isStartNewActivity()) {
mWebView.setWebViewClient(new MainWebViewClient());
}
mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
mWebView.setWebChromeClient(new MainWebChromeClient());
mWebView.loadUrl(loadUrl);
}
private class MainWebChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url,
String message, JsResult result) {
Ln.i("message");
result.confirm();
return true;
}
/*
* Since API Level 8
*/
@Override
public boolean onConsoleMessage(
ConsoleMessage consoleMessage) {
return super.onConsoleMessage(consoleMessage);
}
@Override
public void onProgressChanged(WebView view,
int newProgress) {
}
}
private class MainWebViewOnKeyListener implements
OnKeyListener {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& mWebView.canGoBack()) { // 表示按返回键时的操作
mWebView.goBack(); // 后退
// mWebView.goForward();//前进
return true;
}
}
return false;
}
}
/**
* 如果页面中链接,如果希望点击链接继续在当前browser中响应, 而不是新开Android的系统browser中响应该链接,必须覆盖
* webview的WebViewClient对象。
*/
public class MainWebViewClient extends WebViewClient {
public boolean shouldOverviewUrlLoading(WebView view,
String url) {
view.loadUrl(url);
return true;
}
public void onPageStarted(WebView view, String url,
Bitmap favicon) {
}
public void onPageFinished(WebView view, String url) {
}
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
}
}
public boolean isStartNewActivity() {
return startNewActivity;
}
public void setStartNewActivity(boolean startNewActivity) {
this.startNewActivity = startNewActivity;
}
public boolean isEnableBack() {
return enableBack;
}
public void setEnableBack(boolean enableBack) {
this.enableBack = enableBack;
}
}
3.3 向报表中传值并提供后台Java调用的action:ChartAction
但是本次在页面中没有体现相对应的接受参数代码。
package com.zf.util.chart;
import android.app.Activity;
import android.webkit.JavascriptInterface;
import android.widget.Toast;
import com.google.gson.Gson;
import com.zf.util.Strings;
/**
* js方法一定要加@JavascriptInterface 否则 does not work on API 17
*
* @author 曾凡
* @time 2014年5月16日 下午1:27:49
*/
public class ChartAction {
private Activity mActivity;
private ChartEntity entity;
public ChartAction(Activity activity,
ChartEntity entity) {
this.mActivity = activity;
this.entity = entity;
}
/**
* java 将数据传给js 通过loadUrl()调用 js方法
*/
@JavascriptInterface
public String initDatas() {
String jsonStr = new Gson().toJson(entity);
return jsonStr;
}
/**
* js 将数据传给 java 通过WebView 的addJavascriptInterface()方法 映射一个对象
* 然后再js中通过javascript:对象.方法(参数)的方式调用
*
* @param s
*/
@JavascriptInterface
public void updateDatas(String jsMsg) {
ChartEntity entity = new Gson().fromJson(
Strings.toString(jsMsg), ChartEntity.class);
Toast.makeText(mActivity,
"我是从Js星来的JSON,我现在是JAVA类:" + entity.toString(),
Toast.LENGTH_SHORT).show();
}
}
3.3 编写要向前台发送的POJO实体类,可以用Gson直接转
package com.zf.util.chart;
/**
* @author 曾凡
* @time 2014年6月10日 上午10:09:10
*/
public class ChartEntity {
}
3.4 layout文件 fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<WebView
android:id="@+id/doughnut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<WebView
android:id="@+id/line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<WebView
android:id="@+id/pie"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<WebView
android:id="@+id/polarArea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<WebView
android:id="@+id/radar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<WebView
android:id="@+id/sixup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</ScrollView>
4. 运行结果
5.源代码