本节开始,进行代码的实战练习。我的这个App是管理保险客户信息的,数据采用Sqlite存储在本地手机上,第一次使用需要先登记自己的个人信息,这个功能非常简单,也无关紧要,我是拿这个练手,方便做后面复杂的功能。
- 效果图
废话不多说,先看看个人信息的效果。
主页右上角一个[设置]按钮,点击按钮会弹出对话框,目前只有一个[我的信息]用于查看个人信息。
点击弹出框上的[我的信息],这时会进行个人信息详细列表,点击[返回]按钮会回到主页,而点击[修改]按钮会跳转到个人信息修改页面。
下图是从[我的信息]页面点击[编辑]按钮,跳转到的个人信息修改页面。
如果是第一次使用该程序,会被默认跳转到这个页面,并且没有返回按钮。
点击保存按钮会进行输入有效性验证,如果表单数据有错会在页面提示错误信息。
- 数据库相关
如果不了解SQLite用法,建议先看看[学习系列(5)-SQLite数据库]。
个人信息建表代码如下:
StringBuilder user_info = new StringBuilder(); user_info.append("CREATE TABLE IF NOT EXISTS \"user_info\" ("); user_info.append("\"id\" INTEGER NOT NULL,"); user_info.append("\"name\" varchar(99),"); user_info.append("\"sex\" INTEGER,"); user_info.append("\"birthday\" varchar(32),"); user_info.append("\"mobile_phone\" varchar(32),"); user_info.append("\"email\" varchar(99),"); user_info.append("\"delete_flag\" INTEGER,"); user_info.append("\"user_type\" INTEGER,"); user_info.append("\"update_time\" varchart(99),"); user_info.append("\"id_number\" varchart(99),"); user_info.append("\"qq_number\" varchart(99),"); user_info.append("\"address\" varchart(999),"); user_info.append("PRIMARY KEY (\"id\")"); user_info.append(");"); db.execSQL(user_info.toString());
对应的JavaBean如下,为了方便,我的属性名全部与数据库字段一致,某些带下划线的也就没使用驼峰命名模式。
public class UserInfo extends BasePO{ private static final long serialVersionUID = -8834697836148097731L; private Long id; private String name; private int sex; private String birthday; private String mobile_phone; private String id_number; private String qq_number; private String email; private String address; private int delete_flag; private int user_type; private String update_time; ...... }
而Manager类似于DAO层,嫌麻烦,没有分开,增删改查全部在BaseManagerImpl封装好的,有特殊SQL才在UserManager中实现。
public class UserManager extends BaseManagerImpl<UserInfo>{ public UserManager(Context context) { super(context); super.TABLE = "user_info"; super.clazz = UserInfo.class; } public UserInfoBO getCurrentUser(){ String sql = "SELECT * FROM "+TABLE+" ORDER BY update_time DESC"; List<UserInfo> userList = super.findBySql(sql, null, 1, 1); if(!ObjectUtils.isEmpty(userList)){ return new UserInfoBO(userList.get(0)); } return null; } }
public class BaseManagerImpl<T> implements BaseManager<T> { protected String LOG_TAG = "BaseManagerImpl"; protected String TABLE = null; protected DBHelper dbHelper = null; protected Class clazz = null; protected Context context = null; public BaseManagerImpl(Context context) { super(); dbHelper = BeanFactory.getDBHelper(context); } @Override public long save(T t) { SQLiteDatabase db = dbHelper.getWritableDatabase(); return db.insert(TABLE, null, ClassUtils.getContentValues(t)); } @Override public int delete(Serializable id) { SQLiteDatabase db = dbHelper.getWritableDatabase(); return db.delete(TABLE, "id=?", new String[]{id.toString()}); } @Override public int update(T t) { SQLiteDatabase db = dbHelper.getWritableDatabase(); try { return db.update(TABLE, ClassUtils.getContentValues(t), "id=?", new String[]{ClassUtils.getFieldValue(t, "id").toString()}); } catch (Exception e) { Log.e(LOG_TAG, "反射无法找到对象的ID值", e); return 0; } } @Override public T get(Serializable id) { String getSQL = "SELECT * FROM "+TABLE+" WHERE id=?"; List<T> list = this.findBySql(getSQL, new String[]{id.toString()}, 0, 0); if(!ObjectUtils.isEmpty(list)){ return list.get(0); } return null; } @Override public List<T> findBySql(String sql, String[] params,int pageSize,int pageNo) { if(StringUtils.isBlank(sql)){ throw new RuntimeException("findBySql的sql不能为空!"); } if(pageSize != 0 && pageNo != 0){//分页操作 int begin = (pageSize - 1)*pageNo; sql = sql + " limit "+begin + ","+pageNo; } SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.rawQuery(sql, params); List<T> tList = null; try { tList = ClassUtils.getObject(cursor, clazz); } catch (Exception e) { Log.e(LOG_TAG, "反射创建对象失败,clazz:"+clazz.getName(), e); }finally{ cursor.close(); } return tList; } @Override public List<Map<String,String>> find(String sql,String[] params,int pageSize,int pageNo){ if(StringUtils.isBlank(sql)){ throw new RuntimeException("findBySql的sql不能为空!"); } if(pageSize != 0 && pageNo != 0){//分页操作 int begin = (pageSize - 1)*pageNo; sql = sql + " limit "+begin + ","+pageNo; } SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.rawQuery(sql, params); List<Map<String,String>> list = new ArrayList<Map<String,String>>(); try { String[] columnNames = cursor.getColumnNames(); Map<String,String> map = null; while (cursor.moveToNext()) { map = new HashMap<String, String>(); for (String column : columnNames) { map.put(column, cursor.getString(cursor.getColumnIndex(column))); list.add(map); } } } catch (Exception e) { Log.e(LOG_TAG, "反射创建对象失败,clazz:"+clazz.getName(), e); }finally{ cursor.close(); } return list; } @Override public void updateBySql(String sql, Object[] params) { SQLiteDatabase db = dbHelper.getWritableDatabase(); db.execSQL(sql, params); } @Override public List<T> findAll() { String findAllSql = "SELECT * FROM "+TABLE; return this.findBySql(findAllSql, null, 0, 0); } }
- 开发过程
数据库存储准备好之后,就是开发实体功能。因为采用的是Web开发,所以肯定会涉及HTML和javascript文件,我将这些文件全部放在assets目录下,如下图所示。
------>入口界面
应用程序的入口界面是home.html,前面提到过JqueryMobile的转场方式采用的是AJAX的形式转场,也就是说所有的跳转都是在home.html中操作,所以home.html一定要包含所有的css和js文件,而其它html则完全不需要再单独引用js等(引用了也无效)。
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="../scripts/jquery.mobile-1.3.2/jquery.mobile-1.3.2.min.css" type="text/css"> <script src="../scripts/jquery.mobile-1.3.2/jquery.js" type="text/javascript" > </script> <script src="../scripts/jquery.mobile-1.3.2/jquery.mobile-1.3.2.min.js" type="text/javascript" > </script> <script src="../scripts/bless.ui.core.js" type="text/javascript" > </script> <script src="../scripts/home/bless.home.js" type="text/javascript" > </script> <script src="../scripts/insurer/bless.insurer.js" type="text/javascript" > </script> <script src="../scripts/insure_remind/bless.insurer_remind.js" type="text/javascript" > </script> <script src="../scripts/self/bless.self.js" type="text/javascript" > </script> <script src="../scripts/insurance_company/bless.company.js" type="text/javascript" > </script> <title> </title> </head> <body> <div data-role="page" id="home_index_page"> ...... </div> </body>
每次用户进入home.html页面都会先检查用户是否注册个人信息,如果没有则会直接跳转到个人信息新增页面(self_edit.html)。
$(document).on("pageinit", "#home_index_page", function() { initData_home(); }); //全部变量 用于存储当前用户 var CURRENT_USER; function initData_home() { var currentUserJson = javascriptUser.getCurrentUser(); if (!$.isNull(currentUserJson)) { CURRENT_USER = $.parseJSON(currentUserJson); $("#home_index_page").find("#header_h1").html(CURRENT_USER.name); } else { $.changePageInitData("self/self_edit.html","self_edit_page",function(page, data, params){ javascriptUser.toUserNew(); initData_self_edit(page); }); } }
注意一点:javascriptUser不是我在javascript中定义的,而是Android的WebView控件自己提供的后台与前台数据交互的接口,这个是一个Java类,你可以在里面编写各种后台代码,然后在前台通过[java类.方法]的形式调用后台数据,非常方便。但是注意这个Java类的参数和返回值最好都用最简单的数据类型(我基本都是用String)。
public class JavascriptUser { protected Activity activity; protected AppContext app; protected UserManager userManager; protected InsurerInfoManager insurerInfoManager; protected InsurancesManager insurancesManager; protected ImageInfoManager imageInfoManager; protected InsuranceCompanyManager insuranceCompanyManager; public JavascriptUser(Activity activity) { super(); this.activity = activity; app = (AppContext) activity.getApplication(); userManager = (UserManager) BeanFactory.getDBManager(UserManager.class, activity); insurerInfoManager = (InsurerInfoManager) BeanFactory.getDBManager(InsurerInfoManager.class, activity); insurancesManager = (InsurancesManager) BeanFactory.getDBManager(InsurancesManager.class, activity); imageInfoManager = (ImageInfoManager) BeanFactory.getDBManager(ImageInfoManager.class, activity); insuranceCompanyManager = (InsuranceCompanyManager) BeanFactory.getDBManager(InsuranceCompanyManager.class, activity); } ...... }
在MainActivity中注册与前端关联。
/** javascript与Java对象映射,页面可使用javascript:ajax.xx()来调用AjaxManager的方法 */ webView.addJavascriptInterface(new JavascriptUser(MainActivity.this), "javascriptUser");
有了JavascriptUser后台接口就非常方便了,你就可以用在里面写代码逻辑来查询数据库数据,判断用户是否存在。
------>新增/修改页面
新增和修改因为文本元素一样,所以共用一个页面。根据我的开发习惯,代码逻辑先不写,而是先把界面UI做好,下面是self_edit.html页面代码。
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"> <title> </title> </head> <body> <div data-role="page" data-control-title="修改我的信息" id="self_edit_page"> <div data-theme="b" data-role="header" data-position="fixed"> <a id="a_back" data-role="button" data-rel="back" href="#" class="ui-btn-left" data-icon="back">返回</a> <h3> 修改我的信息 </h3> <a id="a_save" data-role="button" data-theme="b" href="#" data-icon="check" data-iconpos="left" class="ui-btn-right"> 保存 </a> </div> <div data-role="content"> <h5 style="color:red" id="error_msg"></h5> <form method="post" action="#"> <input type="hidden" name="id" id="id" > <input type="hidden" name="delete_flag" id="delete_flag" > <input type="hidden" name="user_type" id="user_type" > <div role="main" class="ui-content"> <div class="ui-field-contain" data-controltype="textinput"> <label for="name"> 姓名 </label> <input name="name" id="name" placeholder="您的姓名..." value="" type="text"> </div> <div id="sex" class="ui-field-contain" data-controltype="radiobuttons"> <fieldset data-role="controlgroup" data-type="horizontal"> <legend> 性别 </legend> <input id="radio1" name="sex" value="1" type="radio" checked="checked"> <label for="radio1"> 男 </label> <input id="radio2" name="sex" value="2" type="radio"> <label for="radio2"> 女 </label> </fieldset> </div> <div class="ui-field-contain" data-controltype="dateinput"> <label for="birthday"> 生日 </label> <input name="birthday" id="birthday" placeholder="您的出生日期..." value="" type="date"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="id_number"> 身份证号 </label> <input name="id_number" id="id_number" placeholder="您的身份证号码..." value="" type="text"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="mobile_phone"> 移动电话 </label> <input name="mobile_phone" id="mobile_phone" placeholder="您的手机号码..." value="" type="tel"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="email"> 电子邮箱 </label> <input name="email" id="email" placeholder="您的E-Mail地址..." value="" type="email"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="qq_number"> QQ </label> <input name="qq_number" id="qq_number" placeholder="您的QQ号码..." value="" type="text"> </div> <div class="ui-field-contain" data-controltype="textarea"> <label for="address"> 联系地址 </label> <textarea name="address" id="address" placeholder="你的直接联系地址..."></textarea> </div> </div> </form> </div> </div> </body> </html>
整个页面都是采用JqueryMobile样式,对于新手不知道怎么做页面布局的,我建议到JqueryMobile中文站了解,该站点首页有一个“jquery mobile UI builder”页面元素在线设计器,你可以通过拖动控件的形式设计页面元素,然后选择“inspect code”查看代码。
新增修改页面唯一的交互操作就是[保存]按钮,当用户点击[保存]按钮时,首先用js获取页面元素的值,然后以参数的形式调用与后台交互的JavascriptUser接口中的saveUserInfo方法执行输入有效性和保存操作。
$(document).on("pageinit", "#self_edit_page", function() { $("#self_edit_page").find("#a_save").unbind("click").bind("click",function(){ //保存 var pageDom = $("#self_edit_page"); var id = pageDom.find("#id").val(); var name = pageDom.find("#name").val(); //radio button获取值得方式 var sex = pageDom.find('input[name="sex"]:checked').val(); var birthday = pageDom.find("#birthday").val(); var mobilePhone = pageDom.find("#mobile_phone").val(); var email = pageDom.find("#email").val(); var delete_flag = pageDom.find("#delete_flag").val(); var user_type = pageDom.find("#user_type").val(); var id_number = pageDom.find("#id_number").val(); var qq_number = pageDom.find("#qq_number").val(); var address = pageDom.find("#address").html(); //调用JavascriptUser的saveUserInfo保存信息 var result = javascriptUser.saveUserInfo(id, name, sex, birthday, mobilePhone, email, delete_flag, user_type, id_number, qq_number, address); if ($.startWith(result,"true,")) {//返回true则保存成功 if($.isNull(id)){//第一次注册后返回到主页 $.mobile.changePage ('../home.html'); }else{//编辑操作返回 个人详细信息页面 $.changePageInitData("self_detail.html","self_detail_page",function(page, data, params){ initData_self_Detail(page, result.substring("true,".length) ); }); } } else {//返回其它信息则将错误信息显示在页面 $("#self_edit_page").find("#error_msg").html(result); } }); });
public String saveUserInfo(String id_,String name,String sex,String birthday,String mobile_phone,String email,String deleteFlag_,String userType_, String id_number,String qq_number,String address){ try { /**先做输入有效性验证*/ List<Validator> list = new ArrayList<Validator>(); list.add( new Validator(ValidateUtils.ValidateEnum.EMPTY, "姓名", new Object[]{name}) ); list.add( new Validator(ValidateUtils.ValidateEnum.CHARACTERS, "姓名", new Object[]{name.trim(),"<>'\""}) ); if(StringUtils.isNotBlank(birthday)){ list.add( new Validator(ValidateUtils.ValidateEnum.DATE, "生日", new Object[]{birthday,"yyyy-MM-dd"}) ); } if(StringUtils.isNotBlank(mobile_phone)){ list.add( new Validator(ValidateUtils.ValidateEnum.NUMBER, "移动电话", new Object[]{mobile_phone}) ); } if(StringUtils.isNotBlank(email)){ list.add( new Validator(ValidateUtils.ValidateEnum.EMAIL, "E-Mail", new Object[]{email}) ); } if(StringUtils.isNotBlank(qq_number)){ list.add( new Validator(ValidateUtils.ValidateEnum.NUMBER, "QQ", new Object[]{qq_number}) ); } String check = ValidateUtils.validateList(list); if(StringUtils.isNotBlank(check)){ return check; } /**再做入库操作*/ boolean edit = StringUtils.isNotBlank(id_); Long id = StringUtils.isNotBlank(id_) ? Long.valueOf(id_) : UserInfo.uuid(); Integer delete_flag = Enums.DeleteEnum.AVAILABLE.getKey(); Integer user_type = StringUtils.isNotBlank(userType_) ? Integer.valueOf(userType_) : Enums.UserTypeEnum.USER.getKey(); String update_time = DateUtil.date2string(new Date(), DateUtil.yyyy_MM_dd_HH_mm_ss); UserInfo user = new UserInfo(id, name, Integer.valueOf(sex), birthday, mobile_phone, id_number, qq_number, email, address, delete_flag, user_type, update_time); if(edit){ userManager.update(user); Log.i(Enums.LogTagEnum.COMMON.getKey(), "修改个人信息:"+user.toString()); }else{ userManager.save(user); Log.i(Enums.LogTagEnum.COMMON.getKey(), "新增个人信息:"+user.toString()); } // 初始化当前用户 app.setUser(new UserInfoBO(user)); return "true,"+user.getId(); } catch (Exception e) { Log.e(Enums.LogTagEnum.COMMON.getKey(), "输入异常:"+e.getMessage(), e); return "输入异常:"+e.getMessage(); } }
我写了一个非常非常简单的Validator验证组件,因为为了方便写了很多小组件,具体逻辑在后面章节[组件化]统一说明。
------>个人信息详细页面
在首页选择"我的信息"可以跳转到个人信息页面,首先先看self_detail.html页面代码。
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"> <title> </title> </head> <body> <!-- data-dom-cache="true" --> <div data-role="page" data-control-title="我的信息" id="self_detail_page" > <div data-theme="b" data-role="header" data-position="fixed"> <a data-role="button" data-rel="back" data-transition="slide" href="#" class="ui-btn-left" data-icon="back">返回</a> <h3> 我的信息 </h3> <a id="a_edit" data-role="button" data-theme="b" href="#" data-icon="edit" data-iconpos="left" class="ui-btn-right"> 修改 </a> </div> <div data-role="content"> <ul data-role='listview' id="ul_self_detail"> </ul> </div> </div> </body> </html>
下面这段是转场到self_detail.html的逻辑代码,在转场到self_detail.html时会调用JavascriptUser接口获取个人信息数据。
$(document).on("pageinit", "#home_setting_page", function() { $("#home_setting_page").find("#a_editSelf").unbind("click").bind("click", function() { $.changePageInitData("self/self_detail.html","self_detail_page",function(page, data, params){ initData_self_Detail(page,CURRENT_USER.id); }); }); }); function initData_self_Detail(pageDOM,id) { if (id != undefined) { //修改操作 var userJson = javascriptUser.getUser(id); var currentUser = $.parseJSON(userJson); var DOM = pageDOM.find("#ul_self_detail"); var html = ""; html = html + "<li><p>姓名:"+currentUser.name+"</p></li>"; html = html + "<li><p>性别:"+ (currentUser.sex==1 ? "男" : "女") +"</p></li>"; html = html + "<li><p>生日:"+currentUser.birthday+"</p></li>"; html = html + "<li><p>移动电话:"+currentUser.mobile_phone+"</p></li>"; html = html + "<li><p>电子邮箱:"+currentUser.email+"</p></li>"; html = html + "<li><p>身份证号:"+currentUser.id_number+"</p></li>"; html = html + "<li><p>QQ号:"+currentUser.qq_number+"</p></li>"; html = html + "<li><p>联系地址:"+currentUser.address+"</p></li>"; DOM.html(html); //只有执行刷新操作才能出ListView样式 DOM.listview("refresh"); }else{ pageDOM.find("#a_back").hide(); } }
------>详情页面到修改页面
最后一个功能是self_detail.html页面点击[修改]按钮进入self_edit.html页面并且将数据回填到页面元素中。
$(document).on("pageinit", "#self_detail_page", function() { $("#self_detail_page").find("#a_edit").unbind("click").bind("click",function(){ $.changePageInitData("self_edit.html","self_edit_page",function(page, data, params){ initData_self_edit(page,CURRENT_USER.id); }); }); }); function initData_self_edit(pageDOM,id) { if (id != undefined) { //修改操作 var userJson = javascriptUser.getUser(id); var currentUser = $.parseJSON(userJson); pageDOM.find("#id").val(currentUser.id); pageDOM.find("#delete_flag").val(currentUser.delete_flag); pageDOM.find("#user_type").val(currentUser.user_type); pageDOM.find("#name").val(currentUser.name); $.radioChecked(pageDOM.find("input[name='sex']"),currentUser.sex); pageDOM.find("#birthday").val(currentUser.birthday); pageDOM.find("#mobile_phone").val(currentUser.mobilePhone); pageDOM.find("#email").val(currentUser.email); pageDOM.find("#id_number").val(currentUser.id_number); pageDOM.find("#qq_number").val(currentUser.qq_number); pageDOM.find("#address").html(currentUser.address); }else{ pageDOM.find("#a_back").hide(); } }
- 注意事项
1、关于WebView与javascript交互:不是只有javascript调用Java,也可以java调用javascript方法。具体可参考博客[Android中webview跟JAVASCRIPT中的交互]
2、关于JqueryMobile页面转场及传参与常规的Java Web有很大不同,可以参考我的博客[学习系列(4)-页面转场及参数传递]或者这个博客[Jquery Mobile中文章跳转传值如何实现]
3、javascript调用Java代码传递的参数和返回值最好都是基本数据类型,我基本用的String,以前试过用JavaBean或者Map之类的不行。
4、如果javascript想从后台获得一个对象或者对象集合,建议在后台转换成JSON字符串,然后在前端通过$.parseJSON转换成对象。一定要注意的是JavaBean中的属性值一定不能包含"\n"(换行符)之类的特殊字符,如果有的话,传给$.parseJSON就会报错,而且LogCat不会直接说这行错了,而是会显示一些莫名其妙的错误提示,很难跟踪。
关于"\n"换行符的解决办法非常简单,就是将字符串"\n"替换成"\\n":
String value ...... value.replaceAll("\r\n", "\\\\r\\\\n").replaceAll("\n", "\\\\n")
5、动态添加listview元素之后一定要刷新listview,否则JqueryMobile不会渲染成自己的效果。
$("#listview").append(......); $("#listview").listview("refresh");
6、radio button动态设置值的话也要刷新checkboxradio,否则页面看起来没效果:
$.radioChecked(pageDOM.find("input[name='sex']"),currentUser.sex); $.radioChecked = function(fn, value) { for (var i = 0; i < fn.length; i++) { if ($(fn[i]).val() == value) { $(fn[i]).attr("checked",true).checkboxradio("refresh"); } else { $(fn[i]).attr("checked",false).checkboxradio("refresh"); } } };
相关推荐
该源码是使用phonegap加jquery mobile开发基于html5 css3的应用的项目例子。可以很好的来学校jquery mobile。
示例中用html5+jquery mobile 开发了一个列车时刻表的demo
用PhoneGap+jQueryMobile开发Android应用实例,很好的android开发学习教材。
PhoneGap+jQueryMobile开发Android应用实例,搭建开发环境
基于Java(Springboot+Mybatis+Mysql)+ JQueryMobile实现个人简介APP 设计这款 APP 是为了让使用者能更清楚清晰地全方面了解我这个人.从我的成长经历、人生阶段和我推荐的东西或物品等等.APP 中还留有我个人的联系...
使用jquery-mobile+html5实现android本地通讯录
Android+Jquerymobile+PhoneGap的项目实例,包括 用这些 js UI实现的 滑屏、触摸、禁横屏、滚动特效。绝对经典,技术绝对齐全, 绝对适合你学习。想学手机软件开发的人,必须选择我的资源, 与我一起进步!!!
“JQuery Mobile学习助手”包含了对JQuery Mobile中的所有组件、接口的详细介绍。对于JQuery Mobile的初学者,可以从中学习JQuery Mobile的所有接口与组件的功能,同时通过范例进行练习;对于JQuery Mobile开发人员...
android phonegao jquery mobile 条码扫描,需导入zxing工程做为lib,此例子是调用服务端页面进行条码扫描,jquerymobile web需放入web工程下
通过本书的学习,读者将会获悉jQuery Mobile的核心特性,以及如何创建可主题化的设计,还会掌握jQuery Mobile的API,以及如何使用PhoneGap来扩展jQuery Mobile。 《jQuery Mobile快速入门》适合想要掌握jQuery ...
android下的Jquery源代码实例和类库!希望对你有所帮助!
没分下载东西了,只好卖我的经典代码了,以下是我通过html5做的多个跨平台应用的demo框架:使用 phonegap 开发android应用框架结构 前台页面用jquery mobile开发,后台用axis2开发实现webservice,前后台用js发送...
You will learn how to build websites and apps for touch devices such as iPhone, iPad, Android, and BlackBerry with the recently developed jQuery Mobile library through sample applications of ...
使用Jquery Mobile设计Android通讯录.pdf
以 HTML5 为主体,搭配JQuery制作网页,再搭配JQueryMobile制作MobileAPP,第4个实例教用户如何将写好的网页打包成Android APP,最后两个实例搭配Web Storage和Web SQL数据库,制作完成后用户能立即将成果打包并放在...
jQuery Mobile音乐播放代码 为什么使用 jQuery Mobile? 通过使用jQuery Mobile 可以 "写更少的代码,做更多的事情" : 它可以通过一个灵活及简单的方式来布局网页,且兼容所有移动设备。 lamp 不同设备使用了...
其次JQuery Mobile通过HTML5的标记与CSS规范来配置与美化页面,对已经学习过这些课程的我们来说,架构清晰,又易于学习. 该APP后端采用了Springboot+Mybatis+Mysql整合框架.传统的Spring去做Java EE开发中,大量的XML...
jQuery Mobile 1.0现已支持当前大部分的主流桌面、智能手机、平板设备及电子阅读平台,包括iOS、Android、WP7、Blackberry、Plam WebOS、Meego、Kindle 3和Fire等,而且还支持一些功能手机和早些版本的浏览器。...
搞这个jquery mobile定位 总的算来也花了我半个月时间了 但现在还是只能在android上才能够精确定位 如果只是jmobile定位 把www文件夹下面的文件放到哪个项目上都可以 没办法 能力有限啊 项目是android+phonegap+...
Android jquerymobile 的简单配置