最近在开发一款报表引擎,里面就需要我会写js做一些简单的混合开发,刚开始学习混合开发的前两天是最郁闷的,毕竟这是一门新的语言,但是还是硬着头皮往上搞了,到第二天的时候就把支持懒加载的Listview倒腾出来了,当然这只是一个最最简单的实现,老手们轻喷,但是对于我这种新手来说绝对是一个重大突破了;

上图,有图有真相;

思路整理

先说一下思路;

  1. 学习写第一个混合应用(互相调用和传参调用);
  2. 学习写一个最简单的ListView;
  3. 实现listView懒加载;
  4. 通过询问做前端的朋友,了解到了Echart这个工具;
  5. 在Echarts官网学习了简单的使用(我这里是折线图入手的),并修改一些参数观察变化;
  6. 学习写一个简单的图表列表实现;

这篇文章我只介绍到如何实现一个简单的ListView,所以只介绍如何实现前三步,其实知道了前三步之后又我就开始对做一个混合的报表应用有点信心了,我相信小伙伴们去做了之后也会有同样的感触;

实现步骤

分三步实现,尽可能的让新手能看懂(我觉得没问题,因为我就是菜鸟),往上有挺多的教程的,不过我感觉还是不够全面吧,淡然我讲的也不一定全面,但是按照这个做绝对能实现;

Step1 混合应用入门

首先明确的是,怎么样才算是一个混合应用,我的定义是既有原生代码又有Web前端代码,而且这两者还能交互(通讯);通讯是最重要的,没有通讯那跟单独写没两样,也就算不上做了混合开发;因此这个环节我觉得最重要的是学会通讯;

通讯就是互相调用嘛,调用的时候可能要带一些参数并拿一些返回值,所以思路就是这样,1. 互相调用,分为带参数和不带参数;2.互相调用,分为带参数有返回值;3.js从安卓取复杂数据

大家直接看代码吧,在座的各位都是精英,我就不多说了;

  1. 布局文件中就一个Webview:
<?xml version="1.0" encoding="utf-8"?>
<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"><WebViewandroid:id="@+id/webView"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@id/ll_btn"android:layout_gravity="center" /></RelativeLayout>
  1. 在java代码中找到这个Webview平配置相关参数;
  private WebView mWebView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);loadWeb();}private void loadWeb() {mWebView = findViewById(R.id.webView);//支持html中javascript解析,不管是不是js和android交互,只要网页中含有js都要mWebView.getSettings().setJavaScriptEnabled(true);//通过获取asset文件,为了方便我把html放在asserts里面了,通过网络获取是一样的String url = "file:///android_asset/index.html";mWebView.loadUrl(url);// 这个很重要了,相当于给js传了一个对象引用,js拿到这个对象可以操作这个JsIntegration对象里面的方法// 大家可以想想一下jni开发,是不是有点有点像,后面跟的"android",是可以自定义的,你写成啥,在js脚本使用的时候就是啥// 比如我这里是android,那么js中使用就是【window.android.方法名】mWebView.addJavascriptInterface(new JsIntegration(),"android");}

JsIntegration的实现很简单,就是实现了Js调用Java带参、不带参、带返回、不带返回;

/*** 这个类是专门提供给js调用的** @author larsonzhong*/
public class JsIntegration {// 带@JavascriptInterface声明的方法才能被js调用到// 这个是不带参的调用@JavascriptInterfacepublic void sayHello() {Log.d("JsIntegration", "java Code:hello world !!!");}// 这个是带参的调用@JavascriptInterfacepublic void setCode(int state) {return "java Code:" + state;}// 这个是不带参带返回的调用@JavascriptInterfacepublic String getHelloString() {return "java Code:hello world !!!";}// 这个是带参带返回的调用@JavascriptInterfacepublic String getConvertedString(String jsStr) {return "js jsStr:" + jsStr;}// 用这个打印日志到logcat@JavascriptInterfacepublic void printLog(String logText){Log.d("JsIntegration",logText+"");}// 这个js从android获取复杂对象的调用@JavascriptInterfacepublic String getList() {// 此处省略lsit的赋值Gson gson2=new Gson();String str=gson2.toJson(list);return "js jsStr:" + jsStr;}
}

注释写的很明白了我这里就不多说了,我们来看下在js脚本中是怎么调用的;首先我们需要一个html页面;

<!DOCTYPE html>
<html>
<head><title>测试</title></head>
<body onLoad="init();">
<div id="temp">h5页面</div>
<button id="btn" onclick="getNativeMsg()">获取NativeString</button>
</body>
<script type="text/javascript">// 这些是页面加载的时候就调用的//1. 无参无返回值的方法window.android.sayHello();//2. 有参无返回值的方法window.android.setCode(200);//3. 不带参带返回的调用var helloText =window.android.getHelloString();console.log(helloText);// 输出helloText信息//3. 带参带返回的调用var message =window.android.getConvertedString("is from js");alert(message);// 弹窗显示message信息//通过方法传字符串function changeText(textString){document.getElementById("temp").innerHTML = textString;}//通过方法传复杂对象,实际上是转换成String传递,然后再通过json转换为对象function handleComplexObject(jsonStr){var obj = JSON.parse(jsonCharts);if (obj &&typeof option ==="object") {window.android.printLog("show end :"+jsonCharts.toString());}}</script>
</html>

实现动态加载ListView

通过上面一个例子我们已经入门了如何做混合开发,接下来我们要动态从安卓的java代码中取数据,为了方便,我简化了java的代码逻辑,直接用写死的数据,不过我相信大家一定能够灵活应用,比如从数据库获取其他地方获取数据,因此就尽可能的简单;

在我看来,尽量把业务逻辑交给App来实现是最好的,因为相对于js,java代码的效率更高,而且如果是从android转向js开发,上手起来也更加容易;

界面部分就不多说了,还是用的一个布局里面一个Webview;
为了开发方便,我把Webview自定义了一个,里面封装了一些通用配置;

/*** 避免重复代码,WEb的配置索性就自定义个View来解决** @author larsonzhong@163.com*/
public class EchartView extends WebView {public EchartView(Context context) {this(context, null);}public EchartView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public EchartView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}@SuppressLint("SetJavaScriptEnabled")private void init() {WebSettings webSettings = getSettings();webSettings.setJavaScriptEnabled(true);webSettings.setJavaScriptCanOpenWindowsAutomatically(true);webSettings.setSupportZoom(false);webSettings.setDisplayZoomControls(false);loadUrl("file:///android_asset/echarts.html");}public void startLoadCharts() {String call = "javascript:startLoadCharts()";// 调用loadUrl方法调用js的startLoadCharts();loadUrl(call);}
}

那么Js中的startLoadCharts方法怎么写呢?(下面的代码我只考虑实现,关于线程同步的我就没考虑了);
echarts.html

<body style="height: 100%; margin: 0">
<!-- 我在最开头放一张图片,ID就叫head_background  -->
<img id="head_background" src="data:images/background.jpg"/>function startLoadCharts(){// 首先知道有多少个数据var dataSize = window.android.getJsonSize();// 占位,给每个位置分配对应的id,以便于在数据获取到之后能够对应填充,反过来数,因为插入时最后插入的在最前面for (var i = (infos.length-1); i >=0; i--) {// 大家发现我这里面有一个data-attribute,这个是自定义属性,因为我要做懒加载,所以需要知道哪些加载过了,这样可以避免重复刷新// 新数据$("#head_background").after("<div id='chart_div_"+i+"' data-attribute=0 style='height: 40%' ></div>");}// 懒加载,要先调用一次,不然要等用户刷了才出来lazyload();}

大家注意到我这里面写了一个懒加载方法,但是我没有把代码贴出来,懒加载是个什么原理呢?简单的来说就是如果这个数据还没加载到界面上,而此时用户还没滑到这个地方,那么这个地方的数据可以暂时不加载,当用户滑到这个位置,发现这个位置的数据没有加载,那就调用显示的方法把数据加载上来,这样可以尽可能的避免界面卡顿,提升交互体验;

那么具体的实现就很简单了;

懒加载

function lazyload(){// 每次滑动就会触发lazyload方法,此时我需要去遍历哪些还没有加载,所以先拿到有多少个数据var jsonSize = window.android.getJsonSize();var seeHeight = document.documentElement.clientHeight; //可见区域高度var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //滚动条距离顶部高度// 遍历每个标签for(var i = 0; i < jsonSize; i++) {var dom =document.getElementById("chart_div_"+i);// 这里就是判断当前标签是否处于可见范围内if (dom.offsetTop < seeHeight + scrollTop) {// 拿到标签的是否加载标志var domValue = dom.dataset.attribute;// 0表示还没有加载(初始值)if (domValue == 0) {// 給自定義屬性賦值,1表示已經賦值dom.setAttribute("data-attribute", 1);//然后我们就可以拿到当前标签对应的数据(可以是复杂对象转成的json)var jsonCharts = window.android.getJsonAt(i);// js提供了json转换方法JSON.parse;,这样我们拿到了对象option var option = JSON.parse(jsonCharts);if (option &&typeof option ==="object") {// todo这个时候我们就可以拿到对象的信息,然后可以为所欲为了}}else{// 表示已经加载过了,不需要处理}}}}// 简单的节流函数//fun 要执行的函数//delay 延迟//time  在time时间内必须执行一次function throttle(fun, delay, time) {var timeout,startTime = new Date();return function() {var context = this,args = arguments,curTime = new Date();clearTimeout(timeout);// 如果达到了规定的触发时间间隔,触发 handlerif (curTime - startTime >= time) {fun.apply(context, args);startTime = curTime;// 没达到触发间隔,重新设定定时器} else {timeout = setTimeout(function(){fun.apply(context, args);}, delay);}};};// 实际想绑定在 scroll 事件上的 handler//function lazyload(event) {}// 采用了节流函数window.addEventListener('scroll',throttle(lazyload,500,1000));

到了这里我们就实现了一个支持内存优化的混合listview,很简单啊有没有;
ps:这个就不要找我要代码了,真的是超级简单了;

有用的话记得点赞哦

超简单的混合开发入门 JS实现安卓Listview相关推荐

  1. android app开发混合开发,混合开发入门 Vue结合Android/iOS开发仿京东项目App

    download:混合开发入门 Vue结合Android/iOS开发仿京东项目App 无需原生开发基础,也能完美呈现京东商城.本课程融合vue.Android.IOS等目前流行的前端和移动端技术,混合 ...

  2. WPF 项目开发入门(五)ListView列表组件 与 Expander组件

    WPF 项目开发入门(一) 安装运行 WPF 项目开发入门(二) WPF 页面布局 WPF 项目开发入门(三)WPF 窗体与页面 WPF 项目开发入门(四) MVVM 模式 与 TreeView树组件 ...

  3. 最简单的混合开发教程:APICloud.

    现在react-native越来越火了,阿里也推出了weex,微信的应用号也开始内测了,未来的世界将会是混合开发的天下. 所以现在还没有接触过混合开发的前端朋友们就要看过来了,这是个最简单的混合开发框 ...

  4. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个可拖动的拼图游戏动画效果~适合初学者~超简单~ |it前端开发

    b站视频演示效果: [web前端特效源码]使用HTML5+CSS3+JavaScript制作一个可拖动的拼图游戏动画效果~适合初学者~超简单~ |前端开发|IT软件 效果图: 完整代码: <!D ...

  5. android字体开发pd,混合开发入门 Vue结合Android/iOS开发仿京东项目App

    无需原生开发基础,也能完美呈现京东商城.本课程融合vue.Android.IOS等目前流行的前端和移动端技术,混合开发经典电商APP--京东.课程将各种复杂功能与知识点完美融合,从技术原理到开发上线, ...

  6. 混合开发入门,java jdk和android sdk安装配置+模拟器安装配置+android studio运行起项目--windows电脑

    首先分享我安装配置过程中遇到的问题,如果你也遇到了,那么跟着我的安装步骤,或许就没问题了... 1.jdk安装过程中没有提示安装jre,jdk的安装目录下面也没有jre文件夹 2.java不是内部或外 ...

  7. IP 摄像机移动应用 SDK 开发入门教程(安卓版)

    涂鸦智能安卓版摄像机(IP Camera,简称 IPC)SDK 是基于智能生活 App SDK 开发而成. 通过移动应用控制物理网设备是常见的使用场景,但由于设备的品类丰富,增大了应用开发难度.因此  ...

  8. 最简单的AR开发入门教程(一)

    AR开发教程(一)之<零基础篇> 本人文章将在极客之星博客首发更新:www.geekerstar.com注:本教程为零基础教程,暂不涉及脚本方面,只是做一个简单的静态AR模型.目的在于提高 ...

  9. HTMLCSS 超简单的前端设计入门-2!

    文章目录 图片元素 img元素 和a元素连用 和map元素 和figure元素 多媒体元素 video audio 列表元素 有序列表 无序列表 定义列表 容器元素 `div`元素 语义化容器元素 元 ...

最新文章

  1. 面向对象三大特征——继承
  2. 快速构建Windows 8风格应用14-ShareContract概述及原理
  3. Nature论文解读:用于改善加权生物网络信噪比的网络增强方法
  4. 邮件列表统计(网站推广)
  5. Math.abs为Integer.Min_VALUE返回错误的值
  6. 手把手教你搭建开发环境之Java开发
  7. Android O 获取APK文件权限 Demo案例
  8. docker run命令_CVE-2019-14271:Docker cp命令漏洞分析
  9. 【OpenCV】OpenCV函数精讲之 -- 访问图像中的像素--计时函数
  10. 【STM32】关于BOOT引脚和一键下载电路下载的一些事
  11. CentOS 6.7安装Spark 1.5.2
  12. Unix和Windows比较
  13. 【老生谈算法】matlab实现信息光学夫琅禾费衍射源码——夫琅禾费衍射
  14. 矩阵取数游戏【题解】
  15. 利用python对资产收益率进行正态检验
  16. GIS应用技巧之矢量网络分析法
  17. Java教师工资习题
  18. Linux学习笔记-shell脚本-log脚本函数
  19. 位置不可用无法访问E此卷不包含可识别文件系统
  20. hualinux 编程概念 3.11 快速原型模型:以最快最小代价完成产品特性

热门文章

  1. ubuntu tmp目录overflow的解决方案
  2. AI教程之 Stable Diffusion在自己电脑上运行稳定的AI自动艺术创作
  3. 免费制作云图的网站(可以从文章中提取关键字)
  4. 通过使OS X中的一切变得更大来让您大吃一惊
  5. python计算平均数_Python标准库——数学运算
  6. word如何一键全选_如何使用Word全选快捷键快速选中文档?
  7. (PAT)卡拉兹(Callatz)猜想/3n+1猜想
  8. 关于Linux进程你所需要知道的一切都在这里!!
  9. hdu 1210 Eddy's 洗牌问题
  10. 学c语言把电脑弄坏了,一不小心把学校的电脑弄坏了怎么样写检讨四百字