本节开始,进行代码的实战练习。我的这个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"); } } };
相关推荐
jQuery Mobile的设计目标是跨平台兼容,能在iOS、Android、Windows Phone等多款主流移动操作系统上无缝运行。通过使用jQuery Mobile,开发者可以快速构建具有触摸友好的交互和流畅动画的移动应用和网站。 在本书中...
【标题】:“Android + PhoneGap + jQuery Mobile” 这个项目标题揭示了一个使用三种技术栈构建的移动应用程序:Android、PhoneGap和jQuery Mobile。Android是Google主导的开源操作系统,主要用于智能手机和平板...
用PhoneGap+jQueryMobile开发Android应用实例,很好的android开发学习教材。
PhoneGap+jQueryMobile开发Android应用实例,搭建开发环境
在开发列车时刻表的demo时,jQuery Mobile可以帮助快速构建界面布局,如使用数据属性和CSS类来创建可点击的时间表条目,同时实现触摸友好的交互效果,如滑动切换日期或查看详细信息。 在Android平台上,通过WebView...
基于Java(Springboot+Mybatis+Mysql)+ JQueryMobile实现个人简介APP 设计这款 APP 是为了让使用者能更清楚清晰地全方面了解我这个人.从我的成长经历、人生阶段和我推荐的东西或物品等等.APP 中还留有我个人的联系...
《手机模拟器与jQueryMobile深度教程》 在移动互联网飞速发展的今天,手机应用的开发变得日益重要。作为开发者,我们需要有效地测试和调试在不同设备上的应用表现,这就需要用到手机模拟器。同时,jQueryMobile作为...
jQuery Mobile 提供了一系列内置的UI组件,如滑块、日期选择器、切换开关等,它们在`jquery.mobile.external-png-1.4.5.css`、`jquery.mobile.inline-png-1.4.5.css`和minified版本中定义了样式。此外,框架还自动...
《Android与jQuery Mobile:类库解析与实战指南》 在移动开发领域,Android以其开源、灵活的特点备受开发者青睐。为了提升用户体验,许多开发者选择在Android应用中集成Web技术,其中jQuery Mobile是一个广受欢迎的...
在移动应用开发中,将HTML5、jQuery Mobile和Android结合可以构建出跨平台的轻量级应用程序,尤其适合快速原型开发或对原生功能的轻度集成。本教程将聚焦于如何利用jQuery Mobile和HTML5来访问并操作Android设备上的...
在这个“phonegap+jqueryMobile例子”中,我们将深入探讨这两个工具如何协同工作,以及如何利用它们创建Android应用程序。 PhoneGap是一个开源框架,它允许开发者使用HTML、CSS和JavaScript来构建原生的移动应用。...
PhoneGap和jQuery Mobile是开发移动应用的两个重要工具,它们结合使用可以构建跨平台的、交互性强的移动应用。在本实例中,我们将探讨如何利用这两个技术创建一个汇率计算器。 PhoneGap是一个开源框架,它允许...
PhoneGap和jQuery Mobile是两种非常重要的移动应用开发技术,它们结合使用可以构建跨平台的混合应用程序。PhoneGap是由Adobe开发的一个开源框架,它允许开发者使用HTML、CSS和JavaScript来创建原生的移动应用,而...
本文主要介绍了如何在Android的WebView中集成jQuery Mobile,包括设置WebView、加载本地资源、引用jQuery Mobile库以及实现Android与JavaScript的交互。希望对您在开发中实现类似功能有所帮助。更多关于WebView和...
根据 jQuery Mobile 的开发团队公布的信息,该框架致力于支持广泛的移动设备和操作系统,包括但不限于: - **Apple iPhone/iPod Touch** - **Google Android** - **RIM BlackBerry/Playbook OS** - **Nokia Symbian...
学习jQuery Mobile,你将了解到如何创建可滚动的列表(listviews),可滑动的面板(panels),可滑动的选项卡(tabs),可折叠的块(collapsible sets),以及各种表单组件的优化。它还支持动态页面加载,这意味着你...
Android+Jquerymobile+PhoneGap的项目实例,包括 用这些 js UI实现的 滑屏、触摸、禁横屏、滚动特效。绝对经典,技术绝对齐全, 绝对适合你学习。想学手机软件开发的人,必须选择我的资源, 与我一起进步!!!
`jquery.mobile-1.0.1.js`是原始的非压缩版本,代码可读性较高,方便开发者调试和学习。而`jquery.mobile-1.0.1.min.js`则是经过压缩和优化的版本,体积更小,加载速度更快,适合生产环境使用。 **jQuery.mobile-...
“JQuery Mobile学习助手”包含了对JQuery Mobile中的所有组件、接口的详细介绍。对于JQuery Mobile的初学者,可以从中学习JQuery Mobile的所有接口与组件的功能,同时通过范例进行练习;对于JQuery Mobile开发人员...
这个源码示例提供了完整的流程,包括PhoneGap应用结构、jQuery Mobile的Web页面、以及与ZXing交互的Java插件,可以帮助开发者快速理解和实践在Android PhoneGap应用中实现条码扫描功能。通过学习和研究这个例子,...