本节开始,进行代码的实战练习。我的这个App是管理保险客户信息的,数据采用Sqlite存储在本地手机上,第一次使用需要先登记自己的个人信息,这个功能非常简单,也无关紧要,我是拿这个练手,方便做后面复杂的功能。

  • 效果图

废话不多说,先看看个人信息的效果。

主页右上角一个[设置]按钮,点击按钮会弹出对话框,目前只有一个[我的信息]用于查看个人信息。

点击弹出框上的[我的信息],这时会进行个人信息详细列表,点击[返回]按钮会回到主页,而点击[修改]按钮会跳转到个人信息修改页面。

下图是从[我的信息]页面点击[编辑]按钮,跳转到的个人信息修改页面。

如果是第一次使用该程序,会被默认跳转到这个页面,并且没有返回按钮。

点击保存按钮会进行输入有效性验证,如果表单数据有错会在页面提示错误信息。

  • 数据库相关

如果不了解SQLite用法,建议先看看[学习系列(5)-SQLite数据库]。

个人信息建表代码如下:

  1. StringBuilder user_info = new StringBuilder();
  2. user_info.append("CREATE TABLE IF NOT EXISTS \"user_info\" (");
  3. user_info.append("\"id\" INTEGER NOT NULL,");
  4. user_info.append("\"name\"  varchar(99),");
  5. user_info.append("\"sex\"  INTEGER,");
  6. user_info.append("\"birthday\"  varchar(32),");
  7. user_info.append("\"mobile_phone\"  varchar(32),");
  8. user_info.append("\"email\"  varchar(99),");
  9. user_info.append("\"delete_flag\"  INTEGER,");
  10. user_info.append("\"user_type\"  INTEGER,");
  11. user_info.append("\"update_time\"  varchart(99),");
  12. user_info.append("\"id_number\"  varchart(99),");
  13. user_info.append("\"qq_number\"  varchart(99),");
  14. user_info.append("\"address\"  varchart(999),");
  15. user_info.append("PRIMARY KEY (\"id\")");
  16. user_info.append(");");
  17. db.execSQL(user_info.toString());

对应的JavaBean如下,为了方便,我的属性名全部与数据库字段一致,某些带下划线的也就没使用驼峰命名模式。

  1. public class UserInfo extends BasePO{
  2. private static final long serialVersionUID = -8834697836148097731L;
  3. private Long id;
  4. private String name;
  5. private int sex;
  6. private String birthday;
  7. private String mobile_phone;
  8. private String id_number;
  9. private String qq_number;
  10. private String email;
  11. private String address;
  12. private int delete_flag;
  13. private int user_type;
  14. private String update_time;
  15. ......
  16. }

而Manager类似于DAO层,嫌麻烦,没有分开,增删改查全部在BaseManagerImpl封装好的,有特殊SQL才在UserManager中实现。

  1. public class UserManager extends BaseManagerImpl<UserInfo>{
  2. public UserManager(Context context) {
  3. super(context);
  4. super.TABLE = "user_info";
  5. super.clazz = UserInfo.class;
  6. }
  7. public UserInfoBO getCurrentUser(){
  8. String sql = "SELECT * FROM "+TABLE+" ORDER BY update_time DESC";
  9. List<UserInfo> userList = super.findBySql(sql, null, 1, 1);
  10. if(!ObjectUtils.isEmpty(userList)){
  11. return new UserInfoBO(userList.get(0));
  12. }
  13. return null;
  14. }
  15. }
  1. public class BaseManagerImpl<T> implements BaseManager<T> {
  2. protected String LOG_TAG = "BaseManagerImpl";
  3. protected String TABLE = null;
  4. protected DBHelper dbHelper = null;
  5. protected Class clazz = null;
  6. protected Context context = null;
  7. public BaseManagerImpl(Context context) {
  8. super();
  9. dbHelper = BeanFactory.getDBHelper(context);
  10. }
  11. @Override
  12. public long save(T t) {
  13. SQLiteDatabase db = dbHelper.getWritableDatabase();
  14. return db.insert(TABLE, null, ClassUtils.getContentValues(t));
  15. }
  16. @Override
  17. public int delete(Serializable id) {
  18. SQLiteDatabase db = dbHelper.getWritableDatabase();
  19. return db.delete(TABLE, "id=?", new String[]{id.toString()});
  20. }
  21. @Override
  22. public int update(T t) {
  23. SQLiteDatabase db = dbHelper.getWritableDatabase();
  24. try {
  25. return db.update(TABLE, ClassUtils.getContentValues(t), "id=?", new String[]{ClassUtils.getFieldValue(t, "id").toString()});
  26. } catch (Exception e) {
  27. Log.e(LOG_TAG, "反射无法找到对象的ID值", e);
  28. return 0;
  29. }
  30. }
  31. @Override
  32. public T get(Serializable id) {
  33. String getSQL = "SELECT * FROM "+TABLE+" WHERE id=?";
  34. List<T> list = this.findBySql(getSQL, new String[]{id.toString()}, 0, 0);
  35. if(!ObjectUtils.isEmpty(list)){
  36. return list.get(0);
  37. }
  38. return null;
  39. }
  40. @Override
  41. public List<T> findBySql(String sql, String[] params,int pageSize,int pageNo) {
  42. if(StringUtils.isBlank(sql)){
  43. throw new RuntimeException("findBySql的sql不能为空!");
  44. }
  45. if(pageSize != 0 && pageNo != 0){//分页操作
  46. int begin = (pageSize - 1)*pageNo;
  47. sql = sql + " limit "+begin + ","+pageNo;
  48. }
  49. SQLiteDatabase db = dbHelper.getReadableDatabase();
  50. Cursor cursor = db.rawQuery(sql, params);
  51. List<T> tList = null;
  52. try {
  53. tList = ClassUtils.getObject(cursor, clazz);
  54. } catch (Exception e) {
  55. Log.e(LOG_TAG, "反射创建对象失败,clazz:"+clazz.getName(), e);
  56. }finally{
  57. cursor.close();
  58. }
  59. return tList;
  60. }
  61. @Override
  62. public List<Map<String,String>> find(String sql,String[] params,int pageSize,int pageNo){
  63. if(StringUtils.isBlank(sql)){
  64. throw new RuntimeException("findBySql的sql不能为空!");
  65. }
  66. if(pageSize != 0 && pageNo != 0){//分页操作
  67. int begin = (pageSize - 1)*pageNo;
  68. sql = sql + " limit "+begin + ","+pageNo;
  69. }
  70. SQLiteDatabase db = dbHelper.getReadableDatabase();
  71. Cursor cursor = db.rawQuery(sql, params);
  72. List<Map<String,String>> list = new ArrayList<Map<String,String>>();
  73. try {
  74. String[] columnNames = cursor.getColumnNames();
  75. Map<String,String> map = null;
  76. while (cursor.moveToNext()) {
  77. map = new HashMap<String, String>();
  78. for (String column : columnNames) {
  79. map.put(column, cursor.getString(cursor.getColumnIndex(column)));
  80. list.add(map);
  81. }
  82. }
  83. } catch (Exception e) {
  84. Log.e(LOG_TAG, "反射创建对象失败,clazz:"+clazz.getName(), e);
  85. }finally{
  86. cursor.close();
  87. }
  88. return list;
  89. }
  90. @Override
  91. public void updateBySql(String sql, Object[] params) {
  92. SQLiteDatabase db = dbHelper.getWritableDatabase();
  93. db.execSQL(sql, params);
  94. }
  95. @Override
  96. public List<T> findAll() {
  97. String findAllSql = "SELECT * FROM "+TABLE;
  98. return this.findBySql(findAllSql, null, 0, 0);
  99. }
  100. }
  • 开发过程

数据库存储准备好之后,就是开发实体功能。因为采用的是Web开发,所以肯定会涉及HTML和javascript文件,我将这些文件全部放在assets目录下,如下图所示。

------>入口界面

应用程序的入口界面是home.html,前面提到过JqueryMobile的转场方式采用的是AJAX的形式转场,也就是说所有的跳转都是在home.html中操作,所以home.html一定要包含所有的css和js文件,而其它html则完全不需要再单独引用js等(引用了也无效)。

  1. <head>
  2. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  3. <meta name="viewport" content="width=device-width, initial-scale=1">
  4. <link rel="stylesheet" href="../scripts/jquery.mobile-1.3.2/jquery.mobile-1.3.2.min.css" type="text/css">
  5. <script src="../scripts/jquery.mobile-1.3.2/jquery.js" type="text/javascript" >
  6. </script>
  7. <script src="../scripts/jquery.mobile-1.3.2/jquery.mobile-1.3.2.min.js" type="text/javascript" >
  8. </script>
  9. <script src="../scripts/bless.ui.core.js" type="text/javascript" >
  10. </script>
  11. <script src="../scripts/home/bless.home.js" type="text/javascript" >
  12. </script>
  13. <script src="../scripts/insurer/bless.insurer.js" type="text/javascript" >
  14. </script>
  15. <script src="../scripts/insure_remind/bless.insurer_remind.js" type="text/javascript" >
  16. </script>
  17. <script src="../scripts/self/bless.self.js" type="text/javascript" >
  18. </script>
  19. <script src="../scripts/insurance_company/bless.company.js" type="text/javascript" >
  20. </script>
  21. <title>
  22. </title>
  23. </head>
  24. <body>
  25. <div data-role="page" id="home_index_page">
  26. ......
  27. </div>
  28. </body>

每次用户进入home.html页面都会先检查用户是否注册个人信息,如果没有则会直接跳转到个人信息新增页面(self_edit.html)。

  1. $(document).on("pageinit", "#home_index_page", function() {
  2. initData_home();
  3. });
  4. //全部变量 用于存储当前用户
  5. var CURRENT_USER;
  6. function initData_home() {
  7. var currentUserJson = javascriptUser.getCurrentUser();
  8. if (!$.isNull(currentUserJson)) {
  9. CURRENT_USER = $.parseJSON(currentUserJson);
  10. $("#home_index_page").find("#header_h1").html(CURRENT_USER.name);
  11. } else {
  12. $.changePageInitData("self/self_edit.html","self_edit_page",function(page, data, params){
  13. javascriptUser.toUserNew();
  14. initData_self_edit(page);
  15. });
  16. }
  17. }

注意一点:javascriptUser不是我在javascript中定义的,而是Android的WebView控件自己提供的后台与前台数据交互的接口,这个是一个Java类,你可以在里面编写各种后台代码,然后在前台通过[java类.方法]的形式调用后台数据,非常方便。但是注意这个Java类的参数和返回值最好都用最简单的数据类型(我基本都是用String)。

  1. public class JavascriptUser {
  2. protected Activity activity;
  3. protected AppContext app;
  4. protected UserManager userManager;
  5. protected InsurerInfoManager insurerInfoManager;
  6. protected InsurancesManager insurancesManager;
  7. protected ImageInfoManager imageInfoManager;
  8. protected InsuranceCompanyManager insuranceCompanyManager;
  9. public JavascriptUser(Activity activity) {
  10. super();
  11. this.activity = activity;
  12. app = (AppContext) activity.getApplication();
  13. userManager = (UserManager) BeanFactory.getDBManager(UserManager.class, activity);
  14. insurerInfoManager = (InsurerInfoManager) BeanFactory.getDBManager(InsurerInfoManager.class, activity);
  15. insurancesManager = (InsurancesManager) BeanFactory.getDBManager(InsurancesManager.class, activity);
  16. imageInfoManager = (ImageInfoManager) BeanFactory.getDBManager(ImageInfoManager.class, activity);
  17. insuranceCompanyManager = (InsuranceCompanyManager) BeanFactory.getDBManager(InsuranceCompanyManager.class, activity);
  18. }
  19. ......
  20. }

在MainActivity中注册与前端关联。

  1. /** javascript与Java对象映射,页面可使用javascript:ajax.xx()来调用AjaxManager的方法 */
  2. webView.addJavascriptInterface(new JavascriptUser(MainActivity.this), "javascriptUser");

有了JavascriptUser后台接口就非常方便了,你就可以用在里面写代码逻辑来查询数据库数据,判断用户是否存在。

------>新增/修改页面

新增和修改因为文本元素一样,所以共用一个页面。根据我的开发习惯,代码逻辑先不写,而是先把界面UI做好,下面是self_edit.html页面代码。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <title>
  7. </title>
  8. </head>
  9. <body>
  10. <div data-role="page" data-control-title="修改我的信息" id="self_edit_page">
  11. <div data-theme="b" data-role="header" data-position="fixed">
  12. <a id="a_back" data-role="button" data-rel="back" href="#" class="ui-btn-left" data-icon="back">返回</a>
  13. <h3>
  14. 修改我的信息
  15. </h3>
  16. <a id="a_save" data-role="button" data-theme="b" href="#" data-icon="check" data-iconpos="left" class="ui-btn-right">
  17. 保存
  18. </a>
  19. </div>
  20. <div data-role="content">
  21. <h5 style="color:red" id="error_msg"></h5>
  22. <form method="post" action="#">
  23. <input type="hidden" name="id" id="id" >
  24. <input type="hidden" name="delete_flag" id="delete_flag" >
  25. <input type="hidden" name="user_type" id="user_type" >
  26. <div role="main" class="ui-content">
  27. <div class="ui-field-contain" data-controltype="textinput">
  28. <label for="name">
  29. 姓名
  30. </label>
  31. <input name="name" id="name" placeholder="您的姓名..." value="" type="text">
  32. </div>
  33. <div id="sex" class="ui-field-contain" data-controltype="radiobuttons">
  34. <fieldset data-role="controlgroup" data-type="horizontal">
  35. <legend>
  36. 性别
  37. </legend>
  38. <input id="radio1" name="sex" value="1" type="radio" checked="checked">
  39. <label for="radio1">
  40. </label>
  41. <input id="radio2" name="sex" value="2" type="radio">
  42. <label for="radio2">
  43. </label>
  44. </fieldset>
  45. </div>
  46. <div class="ui-field-contain" data-controltype="dateinput">
  47. <label for="birthday">
  48. 生日
  49. </label>
  50. <input name="birthday" id="birthday" placeholder="您的出生日期..." value=""
  51. type="date">
  52. </div>
  53. <div class="ui-field-contain" data-controltype="textinput">
  54. <label for="id_number">
  55. 身份证号
  56. </label>
  57. <input name="id_number" id="id_number" placeholder="您的身份证号码..." value=""
  58. type="text">
  59. </div>
  60. <div class="ui-field-contain" data-controltype="textinput">
  61. <label for="mobile_phone">
  62. 移动电话
  63. </label>
  64. <input name="mobile_phone" id="mobile_phone" placeholder="您的手机号码..." value=""
  65. type="tel">
  66. </div>
  67. <div class="ui-field-contain" data-controltype="textinput">
  68. <label for="email">
  69. 电子邮箱
  70. </label>
  71. <input name="email" id="email" placeholder="您的E-Mail地址..." value="" type="email">
  72. </div>
  73. <div class="ui-field-contain" data-controltype="textinput">
  74. <label for="qq_number">
  75. QQ
  76. </label>
  77. <input name="qq_number" id="qq_number" placeholder="您的QQ号码..." value=""
  78. type="text">
  79. </div>
  80. <div class="ui-field-contain" data-controltype="textarea">
  81. <label for="address">
  82. 联系地址
  83. </label>
  84. <textarea name="address" id="address" placeholder="你的直接联系地址..."></textarea>
  85. </div>
  86. </div>
  87. </form>
  88. </div>
  89. </div>
  90. </body>
  91. </html>

整个页面都是采用JqueryMobile样式,对于新手不知道怎么做页面布局的,我建议到JqueryMobile中文站了解,该站点首页有一个“jquery mobile UI builder”页面元素在线设计器,你可以通过拖动控件的形式设计页面元素,然后选择“inspect code”查看代码。

新增修改页面唯一的交互操作就是[保存]按钮,当用户点击[保存]按钮时,首先用js获取页面元素的值,然后以参数的形式调用与后台交互的JavascriptUser接口中的saveUserInfo方法执行输入有效性和保存操作。

  1. $(document).on("pageinit", "#self_edit_page", function() {
  2. $("#self_edit_page").find("#a_save").unbind("click").bind("click",function(){
  3. //保存
  4. var pageDom = $("#self_edit_page");
  5. var id = pageDom.find("#id").val();
  6. var name = pageDom.find("#name").val();
  7. //radio button获取值得方式
  8. var sex = pageDom.find('input[name="sex"]:checked').val();
  9. var birthday = pageDom.find("#birthday").val();
  10. var mobilePhone = pageDom.find("#mobile_phone").val();
  11. var email = pageDom.find("#email").val();
  12. var delete_flag = pageDom.find("#delete_flag").val();
  13. var user_type = pageDom.find("#user_type").val();
  14. var id_number = pageDom.find("#id_number").val();
  15. var qq_number = pageDom.find("#qq_number").val();
  16. var address = pageDom.find("#address").html();
  17. //调用JavascriptUser的saveUserInfo保存信息
  18. var result = javascriptUser.saveUserInfo(id, name, sex, birthday, mobilePhone, email, delete_flag, user_type, id_number, qq_number, address);
  19. if ($.startWith(result,"true,")) {//返回true则保存成功
  20. if($.isNull(id)){//第一次注册后返回到主页
  21. $.mobile.changePage ('../home.html');
  22. }else{//编辑操作返回 个人详细信息页面
  23. $.changePageInitData("self_detail.html","self_detail_page",function(page, data, params){
  24. initData_self_Detail(page, result.substring("true,".length) );
  25. });
  26. }
  27. } else {//返回其它信息则将错误信息显示在页面
  28. $("#self_edit_page").find("#error_msg").html(result);
  29. }
  30. });
  31. });
  1. public String saveUserInfo(String id_,String name,String sex,String birthday,String mobile_phone,String email,String deleteFlag_,String userType_,
  2. String id_number,String qq_number,String address){
  3. try {
  4. /**先做输入有效性验证*/
  5. List<Validator> list = new ArrayList<Validator>();
  6. list.add( new Validator(ValidateUtils.ValidateEnum.EMPTY, "姓名", new Object[]{name}) );
  7. list.add( new Validator(ValidateUtils.ValidateEnum.CHARACTERS, "姓名", new Object[]{name.trim(),"<>'\""}) );
  8. if(StringUtils.isNotBlank(birthday)){
  9. list.add( new Validator(ValidateUtils.ValidateEnum.DATE, "生日", new Object[]{birthday,"yyyy-MM-dd"}) );
  10. }
  11. if(StringUtils.isNotBlank(mobile_phone)){
  12. list.add( new Validator(ValidateUtils.ValidateEnum.NUMBER, "移动电话", new Object[]{mobile_phone}) );
  13. }
  14. if(StringUtils.isNotBlank(email)){
  15. list.add( new Validator(ValidateUtils.ValidateEnum.EMAIL, "E-Mail", new Object[]{email}) );
  16. }
  17. if(StringUtils.isNotBlank(qq_number)){
  18. list.add( new Validator(ValidateUtils.ValidateEnum.NUMBER, "QQ", new Object[]{qq_number}) );
  19. }
  20. String check = ValidateUtils.validateList(list);
  21. if(StringUtils.isNotBlank(check)){
  22. return check;
  23. }
  24. /**再做入库操作*/
  25. boolean edit = StringUtils.isNotBlank(id_);
  26. Long id = StringUtils.isNotBlank(id_) ? Long.valueOf(id_) : UserInfo.uuid();
  27. Integer delete_flag = Enums.DeleteEnum.AVAILABLE.getKey();
  28. Integer user_type = StringUtils.isNotBlank(userType_) ? Integer.valueOf(userType_) : Enums.UserTypeEnum.USER.getKey();
  29. String update_time = DateUtil.date2string(new Date(), DateUtil.yyyy_MM_dd_HH_mm_ss);
  30. UserInfo user = new UserInfo(id, name, Integer.valueOf(sex), birthday, mobile_phone, id_number, qq_number, email, address, delete_flag, user_type, update_time);
  31. if(edit){
  32. userManager.update(user);
  33. Log.i(Enums.LogTagEnum.COMMON.getKey(), "修改个人信息:"+user.toString());
  34. }else{
  35. userManager.save(user);
  36. Log.i(Enums.LogTagEnum.COMMON.getKey(), "新增个人信息:"+user.toString());
  37. }
  38. // 初始化当前用户
  39. app.setUser(new UserInfoBO(user));
  40. return "true,"+user.getId();
  41. } catch (Exception e) {
  42. Log.e(Enums.LogTagEnum.COMMON.getKey(), "输入异常:"+e.getMessage(), e);
  43. return "输入异常:"+e.getMessage();
  44. }
  45. }

我写了一个非常非常简单的Validator验证组件,因为为了方便写了很多小组件,具体逻辑在后面章节[组件化]统一说明。

------>个人信息详细页面

在首页选择"我的信息"可以跳转到个人信息页面,首先先看self_detail.html页面代码。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <title>
  7. </title>
  8. </head>
  9. <body>
  10. <!-- data-dom-cache="true" -->
  11. <div data-role="page" data-control-title="我的信息" id="self_detail_page" >
  12. <div data-theme="b" data-role="header" data-position="fixed">
  13. <a data-role="button" data-rel="back" data-transition="slide" href="#" class="ui-btn-left" data-icon="back">返回</a>
  14. <h3>
  15. 我的信息
  16. </h3>
  17. <a id="a_edit" data-role="button" data-theme="b" href="#" data-icon="edit" data-iconpos="left" class="ui-btn-right">
  18. 修改
  19. </a>
  20. </div>
  21. <div data-role="content">
  22. <ul data-role='listview' id="ul_self_detail">
  23. </ul>
  24. </div>
  25. </div>
  26. </body>
  27. </html>

下面这段是转场到self_detail.html的逻辑代码,在转场到self_detail.html时会调用JavascriptUser接口获取个人信息数据。

  1. $(document).on("pageinit", "#home_setting_page", function() {
  2. $("#home_setting_page").find("#a_editSelf").unbind("click").bind("click", function() {
  3. $.changePageInitData("self/self_detail.html","self_detail_page",function(page, data, params){
  4. initData_self_Detail(page,CURRENT_USER.id);
  5. });
  6. });
  7. });
  8. unction initData_self_Detail(pageDOM,id) {
  9. if (id != undefined) { //修改操作
  10. var userJson = javascriptUser.getUser(id);
  11. var currentUser = $.parseJSON(userJson);
  12. var DOM = pageDOM.find("#ul_self_detail");
  13. var html = "";
  14. html = html + "<li><p>姓名:"+currentUser.name+"</p></li>";
  15. html = html + "<li><p>性别:"+ (currentUser.sex==1 ? "男" : "女") +"</p></li>";
  16. html = html + "<li><p>生日:"+currentUser.birthday+"</p></li>";
  17. html = html + "<li><p>移动电话:"+currentUser.mobile_phone+"</p></li>";
  18. html = html + "<li><p>电子邮箱:"+currentUser.email+"</p></li>";
  19. html = html + "<li><p>身份证号:"+currentUser.id_number+"</p></li>";
  20. html = html + "<li><p>QQ号:"+currentUser.qq_number+"</p></li>";
  21. html = html + "<li><p>联系地址:"+currentUser.address+"</p></li>";
  22. DOM.html(html);
  23. //只有执行刷新操作才能出ListView样式
  24. DOM.listview("refresh");
  25. }else{
  26. pageDOM.find("#a_back").hide();
  27. }

------>详情页面到修改页面

最后一个功能是self_detail.html页面点击[修改]按钮进入self_edit.html页面并且将数据回填到页面元素中。

  1. $(document).on("pageinit", "#self_detail_page", function() {
  2. $("#self_detail_page").find("#a_edit").unbind("click").bind("click",function(){
  3. $.changePageInitData("self_edit.html","self_edit_page",function(page, data, params){
  4. initData_self_edit(page,CURRENT_USER.id);
  5. });
  6. });
  7. });
  8. function initData_self_edit(pageDOM,id) {
  9. if (id != undefined) { //修改操作
  10. var userJson = javascriptUser.getUser(id);
  11. var currentUser = $.parseJSON(userJson);
  12. pageDOM.find("#id").val(currentUser.id);
  13. pageDOM.find("#delete_flag").val(currentUser.delete_flag);
  14. pageDOM.find("#user_type").val(currentUser.user_type);
  15. pageDOM.find("#name").val(currentUser.name);
  16. $.radioChecked(pageDOM.find("input[name='sex']"),currentUser.sex);
  17. pageDOM.find("#birthday").val(currentUser.birthday);
  18. pageDOM.find("#mobile_phone").val(currentUser.mobilePhone);
  19. pageDOM.find("#email").val(currentUser.email);
  20. pageDOM.find("#id_number").val(currentUser.id_number);
  21. pageDOM.find("#qq_number").val(currentUser.qq_number);
  22. pageDOM.find("#address").html(currentUser.address);
  23. }else{
  24. pageDOM.find("#a_back").hide();
  25. }
  • 注意事项

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":

  1. String value ......
  2. value.replaceAll("\r\n", "\\\\r\\\\n").replaceAll("\n", "\\\\n")

5、动态添加listview元素之后一定要刷新listview,否则JqueryMobile不会渲染成自己的效果。

  1. $("#listview").append(......);
  2. $("#listview").listview("refresh");

6、radio button动态设置值的话也要刷新checkboxradio,否则页面看起来没效果:

    1. $.radioChecked(pageDOM.find("input[name='sex']"),currentUser.sex);
    2. $.radioChecked = function(fn, value) {
    3. for (var i = 0; i < fn.length; i++) {
    4. if ($(fn[i]).val() == value) {
    5. $(fn[i]).attr("checked",true).checkboxradio("refresh");
    6. } else {
    7. $(fn[i]).attr("checked",false).checkboxradio("refresh");
    8. }
    9. }
    10. };

Android+Jquery Mobile学习系列(6)-个人信息设置的更多相关文章

  1. Android+Jquery Mobile学习系列(7)-保险人信息

    [保险人管理]是这个APP最重要的功能,用于保存保险客户的数据,给后面的功能提供数据支撑. 简单说说[保险人管理]功能:主要就是增.删.改.查四个功能,在新增和修改的时候不仅可以保存保险人的姓名.身份 ...

  2. Android+Jquery Mobile学习系列-目录

    最近在研究学习基于Android的移动应用开发,准备给家里人做一个应用程序用用.向公司手机移动团队咨询了下,觉得使用Android的WebView上手最快,因为WebView等于是一个内置浏览器,可以 ...

  3. Android+Jquery Mobile学习系列(9)-总结和代码分享

    经过一个多月的边学习边练手,学会了Android基于Web开发的毛皮,其实开发过程中用Android原生API不是很多,更多的是HTML/Javascript/Css. 个人觉得基于WebView的J ...

  4. Android+Jquery Mobile学习系列(2)-HTML5/Jquery Mobile基础

    本章介绍两个关键字[HTML5]和[Jquery Mobile],简单说这两者的关系是:HTML5作为主体,Jquery Mobile在HTML5的基础上对其进行了优化.装饰. HTML5 HTML5 ...

  5. Android+Jquery Mobile学习系列(8)-保单/生日提醒功能

    其实这个App基本功能早已做完,并且交给老婆试用去了.但由于最近项目要保证稳定,所以持续加班,没有时间写最后一点内容,本节也就简单截图做个说明,不详细叙述实现方式.我会把代码上传到最后一章中,有兴趣的 ...

  6. Android+Jquery Mobile学习系列(3)-创建Android项目

    前两章分别对开发环境和Jquery Mobile基础知识进行了介绍,本章介绍创建一个Android项目,并使用WebView控件显示HTML数据. 首先创建一个Android Application项 ...

  7. Android+Jquery Mobile学习系列(4)-页面跳转及参数传递

    关于页面转场,这个必须得专门列出来说明一下,因为Jquery Mobile与普通的Web发开有一些区别,这个对于新手如果不了解的话,就会钻到死胡同.撸主前段时间就是很急躁地上手开发程序,结果在页面转场 ...

  8. Android+Jquery Mobile学习系列(4)-页面转场及参数传递

    关于页面转场,这个必须得专门列出来说明一下,因为Jquery Mobile与普通的Web发开有一些区别,这个对于新手如果不了解的话,就会钻到死胡同.撸主前段时间就是很急躁地上手开发程序,结果在页面转场 ...

  9. Android+Jquery Mobile学习系列(5)-SQLite数据库

    SQLite是轻量级的.嵌入式的.关系型数据库,目前已经在iPhone.Android等手机系统中使用,SQLite可移植性好,很容易使用,很小,高效而且可靠. 因为Android已经集成了SQLit ...

随机推荐

  1. Failed to resolve com.android.support:support-annotations 26.0.1

    所有当前版本的Google库都存放在 Google的Maven repository (maven.google.com),不在旧的offline-capable support repositori ...

  2. HTML地理位置定位

    最近公司项目需要做一个类似微信朋友圈的互动交友功能,需要显示用户位置信息,因此在网上查了部分资料,记下demo供以后查看学习:(用到了百度api来实现定位功能) <!DOCTYPE html&g ...

  3. HDU_1285_拓扑排序(优先队列)

    确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  4. 为什么有些异常throw出去需要在函数头用throws声明,一些就不用

    throw new IllegalStateException(".");不用在函数头声明throws IllegalStateExceptionthrow new IOExcep ...

  5. PAT_A1133#Splitting A Linked List

    Source: PAT A1133 Splitting A Linked List (25 分) Description: Given a singly linked list, you are su ...

  6. python爬虫16 | 你,快去试试用多进程的方式重新去爬取豆瓣上的电影

    我们在之前的文章谈到了高效爬虫 在 python 中 多线程下的 GIL 锁会让多线程显得有点鸡肋 特别是在 CPU 密集型的代码下 多线程被 GIL 锁搞得效率不高 特别是对于多核的 CPU 来说 ...

  7. Python 1 初识python

    1.Python介绍 Python是一种高级语言,与JAVA C# 等同.可以编写各种应用程序,每种语言都有其合适的应用场景.而Python 的优势在于更加人性化.简便的语法规则,以及针对各种具体场景 ...

  8. noip模拟赛 排序

    分析:因为序列是不严格单调的,所以挪动一个数其实就相当于把这个数给删了.如果a[i] < a[i-1],那么可以删掉a[i],也可以删掉a[i-1](!如果没考虑到这一点就只有90分),删后判断 ...

  9. hdu 4707 bellman

    最短路的优先队列做法: #include<stdio.h> #include<queue> #include<string.h> #define N  100010 ...

  10. Sencha Toucha 2.1 文件上传

    javascript代码: Ext.onReady(function() { Ext.create('Ext.form.Panel', { title: 'Upload a Photo', width ...