安卓APP源码和设计报告——仿淘宝水果商城
最近更新 2024年03月28日
资源编号 875333

安卓APP源码和设计报告——仿淘宝水果商城

郑重承诺丨云炬网络提供安全交易、信息保真!
云炬公益:平台收入的50%以上将进行公益慈善捐赠(不定期公示):
¥ 9.9云朵

VIP 5折、云炬VIP年会员免费升级VIP

升级VIP实现财富自由和身心具足
立即下载 查看演示 升级会员 云炬学堂 升级会员
详情介绍
  1. 项目名称
    仿淘宝水果商城
  2. 项目概述

随着互联网技术地高速发展,计算机进入到每一个人的生活里,从人们的生活方式到整个社会的运转都产生了巨大的变革,而在信息技术发达的今天,互联网的各种娱乐方式都在渗透到人们的生活方式之中,近年来人们生活水平的提高,生活压力的增加,精神生活的空虚,使人们对于精神世界的丰富需求越来越大,因此近年来,电视、电影、音乐等娱乐产业都在飞速发展,而音乐虽然是在人类历史上早就存在的娱乐方式,但在信息技术高速发展的现在,大部分产业都在实现互联网+的概念,而且随着全球数字娱乐业的发展,以及网络传播的快速、高效、便捷,传统的传播方式不能满足人们对于这方面的需求,所以许多传统的产业都在实现数字化。仿淘宝商城的产品展示系统是主要面对用户的产品信息展示,也是用户最终想寻找的信息内容。产品展示系统主要就是将仿淘宝商城中各类产品信息进行实时的发布,用户可以在首页清晰的浏览查询到各类产品信息,而且还提供强大的查询功能。

3、目的与要求

通过一个综合的实例,进一步掌握移动应用程序开发的基本原理和方法,提高基于Android Studio对图形用户界面的设计和开发能力,以及对控件事件处理、数据存储以及网络访问的能力。具体包括如下几个方面:

1)熟练掌握Android开发工具Android Studio的使用。

2)熟练掌握Android线性布局的使用方法,并熟练使用Activity、Fragment、ListView、TextView、Button、EditText、ImageView等视图组件构建具有良好用户体验的App界面。

3)熟练掌握对控件常用事件进行处理的方法。

4)掌握数据存储或网络访问的基本方法。

4、系统实现环境

集成开发环境:Android Studio 3.0及以上

JDK :1.8及以上

Android版本:9.0及以上

Android API:28及以上

5、系统设计与实现

本系统所包含的功能有用户登录、用户注册、首页、分类、发现、搜索等功能。用户登录及注册:初次使用本系统的用户需要注册用户名和密码,登录完成提示您已成功登录后,用户可进入首页浏览商品。首页、分类及发现:用户可以浏览商品,在首页可以搜索所需信息,分类页面有超市,大牌及常用分类。分别是一些日用品,奢侈品及各种电子产品。发现页面是一些水果店铺及水果分类。

登录页面主要代码

安卓APP源码和设计报告——仿淘宝水果商城 安卓APP源码和设计报告——仿淘宝水果商城[/caption] userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100" title="目录 一 安卓应用程序开发背景3 1.1开发背景3 1.2开发环境4 二 安卓应用程序开发理论与方法4 三 记事本应用程序的设计与实现5 3.1 拟解决的问题及目标5 3.2 总体设计6 3.3 详细设计与编码实现6 四 总结23 一 安卓应用程序开发背景 1.1开发背景 1.智能手机的市场 (1)功能多样化的智能手机挑战全球PC出货量 移动互联网时代的来临,直接促进了搭载智能操作系统、具有强大扩展性的智能手机、平板电脑等移动终端产业的蓬勃发展。来自美国最大的风险投资机构KPCB的数据显示,全球智能手机出货量正在以远高于台式电脑、笔记本电脑出货量的速度快速增长,该机构预计2011年全球智能手机出货量将达到4.13亿,超过台式电脑与笔记本电脑出货量的总和。 (2)智能手机的用户使用数量正在高速增长。据市场调研机构Gartner信息,2011年全球智能手机的总出货量将会达到4.68亿部,相比2010年实现了57.7%的增长,而谷歌Android操作系统将会在今年之内成为全球最大的智能手机操作系统。另外,全球市场调研机构IDC预计未来5年中国手机市场上,智能手机替代传统功能手机的趋势将日益明显,未来5年中国智能手机市场复合增长率将达到34.1%,人们对IT设备智能化的向往是这一增长率能够实现的主要因素,并且与其他国家相比,中国智能手机市场的发展空间更加广阔。 (3)操作系统格局预测:Android有望成为智能手机市场主导力量 搭载Android操作系统的智能手机目前已经成为市场上最炙手可热的智能产品。来自美国市场研究机构Gartner的数据显示,Android操作系统所占的市场份额从2008年的0.5%急剧增长到2011年的15.94%。开放的源代码和零成本已经让Android在全世界范围内受到青睐并迅速获得了主要手机厂商和数百万软件开发者的支持,Gartner预计,未来Android系统的市场份额有望超过其他操作系统,从而成为全球第一大智能手机操作系统。 2.安卓手机介绍 安卓手机指的是用Android操作系统的手机。安卓(Android)是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。 同样都是手机上面用的智能系统,安卓的系统是新生系统,界面更为华丽,开源性更强,当然因为是新生系统,所以在第三方软件方面暂时还不太多。因此,安卓应用程序的需求还是很迫切的。 3.软件人才需求 据业内统计,目前国内的Android研发人才缺口至少30万。由于目前Android技术较新,无论是相关书籍、培训还是大学教育,都处于初级阶段,因此Android人才短期将供不应求。从长期来看,随着各种移动应用和手机游戏等内容需求日益增加,也将激励大中小型手机应用开发商加大对Android应用的开发力度,因此Android人才的就业前景也非常广泛。 综上所述,在这样的背景下,安卓有很强的生命力。同时,作为一个新生的系统,其应用程序目前并不多,安卓应用程序的需求还是很迫切的,安卓研发人才的缺口还很大。这些都促进了我们学习开发安卓应用程序。 1.2开发环境 安卓应用程序开发环境如下: ①jdk1.8 ②android studio 4.0 ③Android SDK 二 安卓应用程序开发理论与方法 ButterKnife ButterKnife 是一个专注于 Android 系统的 View 注入框架,以前总是要写很多 findViewById 来找到 View 对象,有了 ButterKnife 可以很轻松地省去这些步骤。使用 ButterKnife 对性能基本没有损失,因为 ButterKnife 用到的注解并不是在运行时反射的,而是在编译的时候生成新的 class。项目集成起来特别方便,使用起来也特别简单。 ButterKnife 的优势: 强大的 View 绑定和 Click 事件处理功能,简化代码,提升开发效率 方便地处理 Adapter 里的 ViewHolder 绑定问题 运行时不会影响 APP 效率,使用配置方便 代码清晰,可读性强 SharedPreferences SharedPreferences 是使用键值对的方式来存储数据的。当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且 SharedPreferences 还支持多种不同的数据类型存储。 SQLite + OrmLite SQLite 是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 KB 的内存就足够了,因而特别适合在移动设备上使用。SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务,所以只要以前是用过其他的关系型数据库,就可以很快地上手 SQLite。 ORM(全称 Object Relation Mapping)叫做对象关系映射,是一种程序设计技术,用于实现面向对象编程语言中不同类型系统的数据之间的转换。它可以直接将 Bean 文件转换成数据库中的表,Bean 中的属性就是表的列,它将繁琐的数据库操作封装成一个 Dao 类,使用 Dao 类和 Bean 可以直接对数据库进行操作,大多数的方法参数只有一个 Bean 对象。 多线程编程 Handler + Message Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是使用 Handler 的 sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到 Handler 的 handleMessage()方法中。 Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。除了 what 字段,Message 还可以使用 arg1 和 arg2 字段来携带一些整型数据,使用 obj 字段携带一个 Object 对象。 Glide Glide 是一款快速高效的开源 Android 媒体管理和图片加载框架,它将媒体解码、内存和磁盘缓存以及资源池打包成一个简单易用的界面。 Glide 支持抓取、解码和显示视频图片、图像和动态 gif。Glide 包括一个灵活的 API,允许开发人员插入几乎任何网络堆栈。默认情况下,Glide 使用了一个定制的基于 HttpUrlConnection 的堆栈,但也包含了可插入谷歌的 Volley 项目或 Square 的 OkHttp 库的实用程序库。 Glide 的主要功能是尽可能平滑快速地滚动任何类型的图像列表,但它也适用于几乎任何需要获取、调整大小和显示远程图像的情况。 RecyclerView 控件 RecyclerView 是一个增强版的 ListView,不仅可以轻松实现和 ListView 同样的效果,还优化了 ListView 中存在的各种不足之处。同时 RecyclerView 支持横向滚动和瀑布流布局 Fragment + ViewPager Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。它和 Activity 同样都能包含布局,同样都有自己的生命周期。甚至可以理解成一个迷你的 Activity。 ViewPager 是 android 扩展包 v4 包中的类,这个类可以让用户左右切换当前的 view。ViewPager 类直接继承了 ViewGroup 类,因此它一个容器类,可以添加其他的 View 类 ViewPager 类需要一个 PagerAdapter 适配器类给它提供数据(类似 RecyclerView)。 ViewPager 经常和 Fragment 一起使用,并且官方还提供了专门的 FragmentPagerAdapter 类供 ViewPager 使用。 三 记事本应用程序的设计与实现 3.1 拟解决的问题及目标 一个简单的记事本应用,在人们繁忙的时候更快速的记笔记,程序要实现的目标有如下几个: 登录注册 笔记顶置 开始游戏笔记增删查改 3.2 总体设计 1、记事本操作流程 先注册一个账号,登录进去,可以添加笔记,编辑笔记,顶置笔记,查找笔记 3.3 详细设计与编码实现 记事本界面 注册界面 新建笔记界面 编辑界面 个人信息界面 核心代码如下: RegisterActivity类 public class RegisterActivity extends AppCompatActivity { @BindView(R.id.btn_register) Button btnRegister; @BindView(R.id.btn_reset) Button btnReset; @BindView(R.id.check_hide_pwd_reg) CheckBox checkHidePwdReg; @BindView(R.id.check_hide_pwd_reg2) CheckBox checkHidePwdReg2; @BindView(R.id.edit_username_reg) EditText editUsernameReg; @BindView(R.id.edit_confirm_pwd_reg) EditText editConfirmPwdReg; @BindView(R.id.edit_email_reg) EditText editEmailReg; @BindView(R.id.edit_password_reg) EditText editPasswordReg; SharedPreferenceUtil spu; private static final String TAG = "RegisterActivity"; private UserDao userDao; private String textUserName; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); } @OnClick({R.id.btn_register, R.id.btn_reset, R.id.check_hide_pwd_reg, R.id.check_hide_pwd_reg2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_register: // 检验非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检验密码 if (comparePwd()) { // 检查邮箱格式 if (checkEmail()) { // 检查邮箱是否可用 if (checkOnlyEmail()) { insertUserIntoDB(); queryAll(); Intent intent = new Intent(RegisterActivity.this, MainActivity.class); intent.putExtra(Constant.HAS_REGISTERED, true); startActivity(intent); finish(); } else { Toast.makeText(this, "邮箱已经被使用", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset: editUsernameReg.setText(""); editPasswordReg.setText(""); editConfirmPwdReg.setText(""); editEmailReg.setText(""); break; case R.id.check_hide_pwd_reg: if (checkHidePwdReg.isChecked()) { // 将密码显示出来 editPasswordReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordReg.setSelection(editPasswordReg.getText().toString().length()); break; case R.id.check_hide_pwd_reg2: if (checkHidePwdReg2.isChecked()) { // 将密码显示出来 editConfirmPwdReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdReg.setSelection(editConfirmPwdReg.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editUsernameReg.getText().toString()) && !"".equals(editPasswordReg.getText().toString()) && !"".equals(editConfirmPwdReg.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textUserName = editUsernameReg.getText().toString(); textPassword = editPasswordReg.getText().toString(); textConfirmPwd = editConfirmPwdReg.getText().toString(); textEmail = editEmailReg.getText().toString(); } /** * 检查邮箱是否可用 * * @return */ public boolean checkOnlyEmail() { List userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100" /> 目录 一 安卓应用程序开发背景3 1.1开发背景3 1.2开发环境4 二 安卓应用程序开发理论与方法4 三 记事本应用程序的设计与实现5 3.1 拟解决的问题及目标5 3.2 总体设计6 3.3 详细设计与编码实现6 四 总结23 一 安卓应用程序开发背景 1.1开发背景 1.智能手机的市场 (1)功能多样化的智能手机挑战全球PC出货量 移动互联网时代的来临,直接促进了搭载智能操作系统、具有强大扩展性的智能手机、平板电脑等移动终端产业的蓬勃发展。来自美国最大的风险投资机构KPCB的数据显示,全球智能手机出货量正在以远高于台式电脑、笔记本电脑出货量的速度快速增长,该机构预计2011年全球智能手机出货量将达到4.13亿,超过台式电脑与笔记本电脑出货量的总和。 (2)智能手机的用户使用数量正在高速增长。据市场调研机构Gartner信息,2011年全球智能手机的总出货量将会达到4.68亿部,相比2010年实现了57.7%的增长,而谷歌Android操作系统将会在今年之内成为全球最大的智能手机操作系统。另外,全球市场调研机构IDC预计未来5年中国手机市场上,智能手机替代传统功能手机的趋势将日益明显,未来5年中国智能手机市场复合增长率将达到34.1%,人们对IT设备智能化的向往是这一增长率能够实现的主要因素,并且与其他国家相比,中国智能手机市场的发展空间更加广阔。 (3)操作系统格局预测:Android有望成为智能手机市场主导力量 搭载Android操作系统的智能手机目前已经成为市场上最炙手可热的智能产品。来自美国市场研究机构Gartner的数据显示,Android操作系统所占的市场份额从2008年的0.5%急剧增长到2011年的15.94%。开放的源代码和零成本已经让Android在全世界范围内受到青睐并迅速获得了主要手机厂商和数百万软件开发者的支持,Gartner预计,未来Android系统的市场份额有望超过其他操作系统,从而成为全球第一大智能手机操作系统。 2.安卓手机介绍 安卓手机指的是用Android操作系统的手机。安卓(Android)是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。 同样都是手机上面用的智能系统,安卓的系统是新生系统,界面更为华丽,开源性更强,当然因为是新生系统,所以在第三方软件方面暂时还不太多。因此,安卓应用程序的需求还是很迫切的。 3.软件人才需求 据业内统计,目前国内的Android研发人才缺口至少30万。由于目前Android技术较新,无论是相关书籍、培训还是大学教育,都处于初级阶段,因此Android人才短期将供不应求。从长期来看,随着各种移动应用和手机游戏等内容需求日益增加,也将激励大中小型手机应用开发商加大对Android应用的开发力度,因此Android人才的就业前景也非常广泛。 综上所述,在这样的背景下,安卓有很强的生命力。同时,作为一个新生的系统,其应用程序目前并不多,安卓应用程序的需求还是很迫切的,安卓研发人才的缺口还很大。这些都促进了我们学习开发安卓应用程序。 1.2开发环境 安卓应用程序开发环境如下: ①jdk1.8 ②android studio 4.0 ③Android SDK 二 安卓应用程序开发理论与方法 ButterKnife ButterKnife 是一个专注于 Android 系统的 View 注入框架,以前总是要写很多 findViewById 来找到 View 对象,有了 ButterKnife 可以很轻松地省去这些步骤。使用 ButterKnife 对性能基本没有损失,因为 ButterKnife 用到的注解并不是在运行时反射的,而是在编译的时候生成新的 class。项目集成起来特别方便,使用起来也特别简单。 ButterKnife 的优势: 强大的 View 绑定和 Click 事件处理功能,简化代码,提升开发效率 方便地处理 Adapter 里的 ViewHolder 绑定问题 运行时不会影响 APP 效率,使用配置方便 代码清晰,可读性强 SharedPreferences SharedPreferences 是使用键值对的方式来存储数据的。当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且 SharedPreferences 还支持多种不同的数据类型存储。 SQLite + OrmLite SQLite 是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 KB 的内存就足够了,因而特别适合在移动设备上使用。SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务,所以只要以前是用过其他的关系型数据库,就可以很快地上手 SQLite。 ORM(全称 Object Relation Mapping)叫做对象关系映射,是一种程序设计技术,用于实现面向对象编程语言中不同类型系统的数据之间的转换。它可以直接将 Bean 文件转换成数据库中的表,Bean 中的属性就是表的列,它将繁琐的数据库操作封装成一个 Dao 类,使用 Dao 类和 Bean 可以直接对数据库进行操作,大多数的方法参数只有一个 Bean 对象。 多线程编程 Handler + Message Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是使用 Handler 的 sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到 Handler 的 handleMessage()方法中。 Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。除了 what 字段,Message 还可以使用 arg1 和 arg2 字段来携带一些整型数据,使用 obj 字段携带一个 Object 对象。 Glide Glide 是一款快速高效的开源 Android 媒体管理和图片加载框架,它将媒体解码、内存和磁盘缓存以及资源池打包成一个简单易用的界面。 Glide 支持抓取、解码和显示视频图片、图像和动态 gif。Glide 包括一个灵活的 API,允许开发人员插入几乎任何网络堆栈。默认情况下,Glide 使用了一个定制的基于 HttpUrlConnection 的堆栈,但也包含了可插入谷歌的 Volley 项目或 Square 的 OkHttp 库的实用程序库。 Glide 的主要功能是尽可能平滑快速地滚动任何类型的图像列表,但它也适用于几乎任何需要获取、调整大小和显示远程图像的情况。 RecyclerView 控件 RecyclerView 是一个增强版的 ListView,不仅可以轻松实现和 ListView 同样的效果,还优化了 ListView 中存在的各种不足之处。同时 RecyclerView 支持横向滚动和瀑布流布局 Fragment + ViewPager Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。它和 Activity 同样都能包含布局,同样都有自己的生命周期。甚至可以理解成一个迷你的 Activity。 ViewPager 是 android 扩展包 v4 包中的类,这个类可以让用户左右切换当前的 view。ViewPager 类直接继承了 ViewGroup 类,因此它一个容器类,可以添加其他的 View 类 ViewPager 类需要一个 PagerAdapter 适配器类给它提供数据(类似 RecyclerView)。 ViewPager 经常和 Fragment 一起使用,并且官方还提供了专门的 FragmentPagerAdapter 类供 ViewPager 使用。 三 记事本应用程序的设计与实现 3.1 拟解决的问题及目标 一个简单的记事本应用,在人们繁忙的时候更快速的记笔记,程序要实现的目标有如下几个: 登录注册 笔记顶置 开始游戏笔记增删查改 3.2 总体设计 1、记事本操作流程 先注册一个账号,登录进去,可以添加笔记,编辑笔记,顶置笔记,查找笔记 3.3 详细设计与编码实现 记事本界面 注册界面 新建笔记界面 编辑界面 个人信息界面 核心代码如下: RegisterActivity类 public class RegisterActivity extends AppCompatActivity { @BindView(R.id.btn_register) Button btnRegister; @BindView(R.id.btn_reset) Button btnReset; @BindView(R.id.check_hide_pwd_reg) CheckBox checkHidePwdReg; @BindView(R.id.check_hide_pwd_reg2) CheckBox checkHidePwdReg2; @BindView(R.id.edit_username_reg) EditText editUsernameReg; @BindView(R.id.edit_confirm_pwd_reg) EditText editConfirmPwdReg; @BindView(R.id.edit_email_reg) EditText editEmailReg; @BindView(R.id.edit_password_reg) EditText editPasswordReg; SharedPreferenceUtil spu; private static final String TAG = "RegisterActivity"; private UserDao userDao; private String textUserName; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); } @OnClick({R.id.btn_register, R.id.btn_reset, R.id.check_hide_pwd_reg, R.id.check_hide_pwd_reg2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_register: // 检验非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检验密码 if (comparePwd()) { // 检查邮箱格式 if (checkEmail()) { // 检查邮箱是否可用 if (checkOnlyEmail()) { insertUserIntoDB(); queryAll(); Intent intent = new Intent(RegisterActivity.this, MainActivity.class); intent.putExtra(Constant.HAS_REGISTERED, true); startActivity(intent); finish(); } else { Toast.makeText(this, "邮箱已经被使用", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset: editUsernameReg.setText(""); editPasswordReg.setText(""); editConfirmPwdReg.setText(""); editEmailReg.setText(""); break; case R.id.check_hide_pwd_reg: if (checkHidePwdReg.isChecked()) { // 将密码显示出来 editPasswordReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordReg.setSelection(editPasswordReg.getText().toString().length()); break; case R.id.check_hide_pwd_reg2: if (checkHidePwdReg2.isChecked()) { // 将密码显示出来 editConfirmPwdReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdReg.setSelection(editConfirmPwdReg.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editUsernameReg.getText().toString()) && !"".equals(editPasswordReg.getText().toString()) && !"".equals(editConfirmPwdReg.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textUserName = editUsernameReg.getText().toString(); textPassword = editPasswordReg.getText().toString(); textConfirmPwd = editConfirmPwdReg.getText().toString(); textEmail = editEmailReg.getText().toString(); } /** * 检查邮箱是否可用 * * @return */ public boolean checkOnlyEmail() { List userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100[/caption]userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100" title="目录 一 安卓应用程序开发背景3 1.1开发背景3 1.2开发环境4 二 安卓应用程序开发理论与方法4 三 记事本应用程序的设计与实现5 3.1 拟解决的问题及目标5 3.2 总体设计6 3.3 详细设计与编码实现6 四 总结23 一 安卓应用程序开发背景 1.1开发背景 1.智能手机的市场 (1)功能多样化的智能手机挑战全球PC出货量 移动互联网时代的来临,直接促进了搭载智能操作系统、具有强大扩展性的智能手机、平板电脑等移动终端产业的蓬勃发展。来自美国最大的风险投资机构KPCB的数据显示,全球智能手机出货量正在以远高于台式电脑、笔记本电脑出货量的速度快速增长,该机构预计2011年全球智能手机出货量将达到4.13亿,超过台式电脑与笔记本电脑出货量的总和。 (2)智能手机的用户使用数量正在高速增长。据市场调研机构Gartner信息,2011年全球智能手机的总出货量将会达到4.68亿部,相比2010年实现了57.7%的增长,而谷歌Android操作系统将会在今年之内成为全球最大的智能手机操作系统。另外,全球市场调研机构IDC预计未来5年中国手机市场上,智能手机替代传统功能手机的趋势将日益明显,未来5年中国智能手机市场复合增长率将达到34.1%,人们对IT设备智能化的向往是这一增长率能够实现的主要因素,并且与其他国家相比,中国智能手机市场的发展空间更加广阔。 (3)操作系统格局预测:Android有望成为智能手机市场主导力量 搭载Android操作系统的智能手机目前已经成为市场上最炙手可热的智能产品。来自美国市场研究机构Gartner的数据显示,Android操作系统所占的市场份额从2008年的0.5%急剧增长到2011年的15.94%。开放的源代码和零成本已经让Android在全世界范围内受到青睐并迅速获得了主要手机厂商和数百万软件开发者的支持,Gartner预计,未来Android系统的市场份额有望超过其他操作系统,从而成为全球第一大智能手机操作系统。 2.安卓手机介绍 安卓手机指的是用Android操作系统的手机。安卓(Android)是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。 同样都是手机上面用的智能系统,安卓的系统是新生系统,界面更为华丽,开源性更强,当然因为是新生系统,所以在第三方软件方面暂时还不太多。因此,安卓应用程序的需求还是很迫切的。 3.软件人才需求 据业内统计,目前国内的Android研发人才缺口至少30万。由于目前Android技术较新,无论是相关书籍、培训还是大学教育,都处于初级阶段,因此Android人才短期将供不应求。从长期来看,随着各种移动应用和手机游戏等内容需求日益增加,也将激励大中小型手机应用开发商加大对Android应用的开发力度,因此Android人才的就业前景也非常广泛。 综上所述,在这样的背景下,安卓有很强的生命力。同时,作为一个新生的系统,其应用程序目前并不多,安卓应用程序的需求还是很迫切的,安卓研发人才的缺口还很大。这些都促进了我们学习开发安卓应用程序。 1.2开发环境 安卓应用程序开发环境如下: ①jdk1.8 ②android studio 4.0 ③Android SDK 二 安卓应用程序开发理论与方法 ButterKnife ButterKnife 是一个专注于 Android 系统的 View 注入框架,以前总是要写很多 findViewById 来找到 View 对象,有了 ButterKnife 可以很轻松地省去这些步骤。使用 ButterKnife 对性能基本没有损失,因为 ButterKnife 用到的注解并不是在运行时反射的,而是在编译的时候生成新的 class。项目集成起来特别方便,使用起来也特别简单。 ButterKnife 的优势: 强大的 View 绑定和 Click 事件处理功能,简化代码,提升开发效率 方便地处理 Adapter 里的 ViewHolder 绑定问题 运行时不会影响 APP 效率,使用配置方便 代码清晰,可读性强 SharedPreferences SharedPreferences 是使用键值对的方式来存储数据的。当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且 SharedPreferences 还支持多种不同的数据类型存储。 SQLite + OrmLite SQLite 是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 KB 的内存就足够了,因而特别适合在移动设备上使用。SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务,所以只要以前是用过其他的关系型数据库,就可以很快地上手 SQLite。 ORM(全称 Object Relation Mapping)叫做对象关系映射,是一种程序设计技术,用于实现面向对象编程语言中不同类型系统的数据之间的转换。它可以直接将 Bean 文件转换成数据库中的表,Bean 中的属性就是表的列,它将繁琐的数据库操作封装成一个 Dao 类,使用 Dao 类和 Bean 可以直接对数据库进行操作,大多数的方法参数只有一个 Bean 对象。 多线程编程 Handler + Message Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是使用 Handler 的 sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到 Handler 的 handleMessage()方法中。 Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。除了 what 字段,Message 还可以使用 arg1 和 arg2 字段来携带一些整型数据,使用 obj 字段携带一个 Object 对象。 Glide Glide 是一款快速高效的开源 Android 媒体管理和图片加载框架,它将媒体解码、内存和磁盘缓存以及资源池打包成一个简单易用的界面。 Glide 支持抓取、解码和显示视频图片、图像和动态 gif。Glide 包括一个灵活的 API,允许开发人员插入几乎任何网络堆栈。默认情况下,Glide 使用了一个定制的基于 HttpUrlConnection 的堆栈,但也包含了可插入谷歌的 Volley 项目或 Square 的 OkHttp 库的实用程序库。 Glide 的主要功能是尽可能平滑快速地滚动任何类型的图像列表,但它也适用于几乎任何需要获取、调整大小和显示远程图像的情况。 RecyclerView 控件 RecyclerView 是一个增强版的 ListView,不仅可以轻松实现和 ListView 同样的效果,还优化了 ListView 中存在的各种不足之处。同时 RecyclerView 支持横向滚动和瀑布流布局 Fragment + ViewPager Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。它和 Activity 同样都能包含布局,同样都有自己的生命周期。甚至可以理解成一个迷你的 Activity。 ViewPager 是 android 扩展包 v4 包中的类,这个类可以让用户左右切换当前的 view。ViewPager 类直接继承了 ViewGroup 类,因此它一个容器类,可以添加其他的 View 类 ViewPager 类需要一个 PagerAdapter 适配器类给它提供数据(类似 RecyclerView)。 ViewPager 经常和 Fragment 一起使用,并且官方还提供了专门的 FragmentPagerAdapter 类供 ViewPager 使用。 三 记事本应用程序的设计与实现 3.1 拟解决的问题及目标 一个简单的记事本应用,在人们繁忙的时候更快速的记笔记,程序要实现的目标有如下几个: 登录注册 笔记顶置 开始游戏笔记增删查改 3.2 总体设计 1、记事本操作流程 先注册一个账号,登录进去,可以添加笔记,编辑笔记,顶置笔记,查找笔记 3.3 详细设计与编码实现 记事本界面 注册界面 新建笔记界面 编辑界面 个人信息界面 核心代码如下: RegisterActivity类 public class RegisterActivity extends AppCompatActivity { @BindView(R.id.btn_register) Button btnRegister; @BindView(R.id.btn_reset) Button btnReset; @BindView(R.id.check_hide_pwd_reg) CheckBox checkHidePwdReg; @BindView(R.id.check_hide_pwd_reg2) CheckBox checkHidePwdReg2; @BindView(R.id.edit_username_reg) EditText editUsernameReg; @BindView(R.id.edit_confirm_pwd_reg) EditText editConfirmPwdReg; @BindView(R.id.edit_email_reg) EditText editEmailReg; @BindView(R.id.edit_password_reg) EditText editPasswordReg; SharedPreferenceUtil spu; private static final String TAG = "RegisterActivity"; private UserDao userDao; private String textUserName; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); } @OnClick({R.id.btn_register, R.id.btn_reset, R.id.check_hide_pwd_reg, R.id.check_hide_pwd_reg2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_register: // 检验非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检验密码 if (comparePwd()) { // 检查邮箱格式 if (checkEmail()) { // 检查邮箱是否可用 if (checkOnlyEmail()) { insertUserIntoDB(); queryAll(); Intent intent = new Intent(RegisterActivity.this, MainActivity.class); intent.putExtra(Constant.HAS_REGISTERED, true); startActivity(intent); finish(); } else { Toast.makeText(this, "邮箱已经被使用", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset: editUsernameReg.setText(""); editPasswordReg.setText(""); editConfirmPwdReg.setText(""); editEmailReg.setText(""); break; case R.id.check_hide_pwd_reg: if (checkHidePwdReg.isChecked()) { // 将密码显示出来 editPasswordReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordReg.setSelection(editPasswordReg.getText().toString().length()); break; case R.id.check_hide_pwd_reg2: if (checkHidePwdReg2.isChecked()) { // 将密码显示出来 editConfirmPwdReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdReg.setSelection(editConfirmPwdReg.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editUsernameReg.getText().toString()) && !"".equals(editPasswordReg.getText().toString()) && !"".equals(editConfirmPwdReg.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textUserName = editUsernameReg.getText().toString(); textPassword = editPasswordReg.getText().toString(); textConfirmPwd = editConfirmPwdReg.getText().toString(); textEmail = editEmailReg.getText().toString(); } /** * 检查邮箱是否可用 * * @return */ public boolean checkOnlyEmail() { List userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100" /> 目录 一 安卓应用程序开发背景3 1.1开发背景3 1.2开发环境4 二 安卓应用程序开发理论与方法4 三 记事本应用程序的设计与实现5 3.1 拟解决的问题及目标5 3.2 总体设计6 3.3 详细设计与编码实现6 四 总结23 一 安卓应用程序开发背景 1.1开发背景 1.智能手机的市场 (1)功能多样化的智能手机挑战全球PC出货量 移动互联网时代的来临,直接促进了搭载智能操作系统、具有强大扩展性的智能手机、平板电脑等移动终端产业的蓬勃发展。来自美国最大的风险投资机构KPCB的数据显示,全球智能手机出货量正在以远高于台式电脑、笔记本电脑出货量的速度快速增长,该机构预计2011年全球智能手机出货量将达到4.13亿,超过台式电脑与笔记本电脑出货量的总和。 (2)智能手机的用户使用数量正在高速增长。据市场调研机构Gartner信息,2011年全球智能手机的总出货量将会达到4.68亿部,相比2010年实现了57.7%的增长,而谷歌Android操作系统将会在今年之内成为全球最大的智能手机操作系统。另外,全球市场调研机构IDC预计未来5年中国手机市场上,智能手机替代传统功能手机的趋势将日益明显,未来5年中国智能手机市场复合增长率将达到34.1%,人们对IT设备智能化的向往是这一增长率能够实现的主要因素,并且与其他国家相比,中国智能手机市场的发展空间更加广阔。 (3)操作系统格局预测:Android有望成为智能手机市场主导力量 搭载Android操作系统的智能手机目前已经成为市场上最炙手可热的智能产品。来自美国市场研究机构Gartner的数据显示,Android操作系统所占的市场份额从2008年的0.5%急剧增长到2011年的15.94%。开放的源代码和零成本已经让Android在全世界范围内受到青睐并迅速获得了主要手机厂商和数百万软件开发者的支持,Gartner预计,未来Android系统的市场份额有望超过其他操作系统,从而成为全球第一大智能手机操作系统。 2.安卓手机介绍 安卓手机指的是用Android操作系统的手机。安卓(Android)是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。 同样都是手机上面用的智能系统,安卓的系统是新生系统,界面更为华丽,开源性更强,当然因为是新生系统,所以在第三方软件方面暂时还不太多。因此,安卓应用程序的需求还是很迫切的。 3.软件人才需求 据业内统计,目前国内的Android研发人才缺口至少30万。由于目前Android技术较新,无论是相关书籍、培训还是大学教育,都处于初级阶段,因此Android人才短期将供不应求。从长期来看,随着各种移动应用和手机游戏等内容需求日益增加,也将激励大中小型手机应用开发商加大对Android应用的开发力度,因此Android人才的就业前景也非常广泛。 综上所述,在这样的背景下,安卓有很强的生命力。同时,作为一个新生的系统,其应用程序目前并不多,安卓应用程序的需求还是很迫切的,安卓研发人才的缺口还很大。这些都促进了我们学习开发安卓应用程序。 1.2开发环境 安卓应用程序开发环境如下: ①jdk1.8 ②android studio 4.0 ③Android SDK 二 安卓应用程序开发理论与方法 ButterKnife ButterKnife 是一个专注于 Android 系统的 View 注入框架,以前总是要写很多 findViewById 来找到 View 对象,有了 ButterKnife 可以很轻松地省去这些步骤。使用 ButterKnife 对性能基本没有损失,因为 ButterKnife 用到的注解并不是在运行时反射的,而是在编译的时候生成新的 class。项目集成起来特别方便,使用起来也特别简单。 ButterKnife 的优势: 强大的 View 绑定和 Click 事件处理功能,简化代码,提升开发效率 方便地处理 Adapter 里的 ViewHolder 绑定问题 运行时不会影响 APP 效率,使用配置方便 代码清晰,可读性强 SharedPreferences SharedPreferences 是使用键值对的方式来存储数据的。当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且 SharedPreferences 还支持多种不同的数据类型存储。 SQLite + OrmLite SQLite 是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 KB 的内存就足够了,因而特别适合在移动设备上使用。SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务,所以只要以前是用过其他的关系型数据库,就可以很快地上手 SQLite。 ORM(全称 Object Relation Mapping)叫做对象关系映射,是一种程序设计技术,用于实现面向对象编程语言中不同类型系统的数据之间的转换。它可以直接将 Bean 文件转换成数据库中的表,Bean 中的属性就是表的列,它将繁琐的数据库操作封装成一个 Dao 类,使用 Dao 类和 Bean 可以直接对数据库进行操作,大多数的方法参数只有一个 Bean 对象。 多线程编程 Handler + Message Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是使用 Handler 的 sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到 Handler 的 handleMessage()方法中。 Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。除了 what 字段,Message 还可以使用 arg1 和 arg2 字段来携带一些整型数据,使用 obj 字段携带一个 Object 对象。 Glide Glide 是一款快速高效的开源 Android 媒体管理和图片加载框架,它将媒体解码、内存和磁盘缓存以及资源池打包成一个简单易用的界面。 Glide 支持抓取、解码和显示视频图片、图像和动态 gif。Glide 包括一个灵活的 API,允许开发人员插入几乎任何网络堆栈。默认情况下,Glide 使用了一个定制的基于 HttpUrlConnection 的堆栈,但也包含了可插入谷歌的 Volley 项目或 Square 的 OkHttp 库的实用程序库。 Glide 的主要功能是尽可能平滑快速地滚动任何类型的图像列表,但它也适用于几乎任何需要获取、调整大小和显示远程图像的情况。 RecyclerView 控件 RecyclerView 是一个增强版的 ListView,不仅可以轻松实现和 ListView 同样的效果,还优化了 ListView 中存在的各种不足之处。同时 RecyclerView 支持横向滚动和瀑布流布局 Fragment + ViewPager Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。它和 Activity 同样都能包含布局,同样都有自己的生命周期。甚至可以理解成一个迷你的 Activity。 ViewPager 是 android 扩展包 v4 包中的类,这个类可以让用户左右切换当前的 view。ViewPager 类直接继承了 ViewGroup 类,因此它一个容器类,可以添加其他的 View 类 ViewPager 类需要一个 PagerAdapter 适配器类给它提供数据(类似 RecyclerView)。 ViewPager 经常和 Fragment 一起使用,并且官方还提供了专门的 FragmentPagerAdapter 类供 ViewPager 使用。 三 记事本应用程序的设计与实现 3.1 拟解决的问题及目标 一个简单的记事本应用,在人们繁忙的时候更快速的记笔记,程序要实现的目标有如下几个: 登录注册 笔记顶置 开始游戏笔记增删查改 3.2 总体设计 1、记事本操作流程 先注册一个账号,登录进去,可以添加笔记,编辑笔记,顶置笔记,查找笔记 3.3 详细设计与编码实现 记事本界面 注册界面 新建笔记界面 编辑界面 个人信息界面 核心代码如下: RegisterActivity类 public class RegisterActivity extends AppCompatActivity { @BindView(R.id.btn_register) Button btnRegister; @BindView(R.id.btn_reset) Button btnReset; @BindView(R.id.check_hide_pwd_reg) CheckBox checkHidePwdReg; @BindView(R.id.check_hide_pwd_reg2) CheckBox checkHidePwdReg2; @BindView(R.id.edit_username_reg) EditText editUsernameReg; @BindView(R.id.edit_confirm_pwd_reg) EditText editConfirmPwdReg; @BindView(R.id.edit_email_reg) EditText editEmailReg; @BindView(R.id.edit_password_reg) EditText editPasswordReg; SharedPreferenceUtil spu; private static final String TAG = "RegisterActivity"; private UserDao userDao; private String textUserName; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); } @OnClick({R.id.btn_register, R.id.btn_reset, R.id.check_hide_pwd_reg, R.id.check_hide_pwd_reg2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_register: // 检验非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检验密码 if (comparePwd()) { // 检查邮箱格式 if (checkEmail()) { // 检查邮箱是否可用 if (checkOnlyEmail()) { insertUserIntoDB(); queryAll(); Intent intent = new Intent(RegisterActivity.this, MainActivity.class); intent.putExtra(Constant.HAS_REGISTERED, true); startActivity(intent); finish(); } else { Toast.makeText(this, "邮箱已经被使用", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset: editUsernameReg.setText(""); editPasswordReg.setText(""); editConfirmPwdReg.setText(""); editEmailReg.setText(""); break; case R.id.check_hide_pwd_reg: if (checkHidePwdReg.isChecked()) { // 将密码显示出来 editPasswordReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordReg.setSelection(editPasswordReg.getText().toString().length()); break; case R.id.check_hide_pwd_reg2: if (checkHidePwdReg2.isChecked()) { // 将密码显示出来 editConfirmPwdReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdReg.setSelection(editConfirmPwdReg.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editUsernameReg.getText().toString()) && !"".equals(editPasswordReg.getText().toString()) && !"".equals(editConfirmPwdReg.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textUserName = editUsernameReg.getText().toString(); textPassword = editPasswordReg.getText().toString(); textConfirmPwd = editConfirmPwdReg.getText().toString(); textEmail = editEmailReg.getText().toString(); } /** * 检查邮箱是否可用 * * @return */ public boolean checkOnlyEmail() { List userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100[/caption]

btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = et_username.getText().toString().trim();
String password = et_password.getText().toString().trim();
if (UIfEmpty.ifEmpty(username, password)) {
Toast.makeText(LoginActivity.this"信息未输入完整", Toast.LENGTH_SHORT).show();
else {
Cursor cursor = db.rawQuery("select username from user where username = ? and password = ?",
new String[]{username, password});
if (cursor.getCount() == 1) {
SharedPreferences.Editor editor = sp.edit();
if (cb_remember.isChecked()) {
editor.putString("username", username);
editor.putString("password", password);
editor.putBoolean("IFCHECK"true);
else {
editor.putBoolean("IFCHECK"false);
}
editor.commit();
startActivity(new Intent(LoginActivity.this, MainActivity.class));
Toast.makeText(LoginActivity.this"登录成功", Toast.LENGTH_SHORT).show();
else {
Toast.makeText(LoginActivity.this"账号或密码错误", Toast.LENGTH_SHORT).show();
}
cursor.close();
}
}
});

注册页面的主要代码

安卓APP源码和设计报告——仿淘宝水果商城 安卓APP源码和设计报告——仿淘宝水果商城[/caption] userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100" title="目录 一 安卓应用程序开发背景3 1.1开发背景3 1.2开发环境4 二 安卓应用程序开发理论与方法4 三 记事本应用程序的设计与实现5 3.1 拟解决的问题及目标5 3.2 总体设计6 3.3 详细设计与编码实现6 四 总结23 一 安卓应用程序开发背景 1.1开发背景 1.智能手机的市场 (1)功能多样化的智能手机挑战全球PC出货量 移动互联网时代的来临,直接促进了搭载智能操作系统、具有强大扩展性的智能手机、平板电脑等移动终端产业的蓬勃发展。来自美国最大的风险投资机构KPCB的数据显示,全球智能手机出货量正在以远高于台式电脑、笔记本电脑出货量的速度快速增长,该机构预计2011年全球智能手机出货量将达到4.13亿,超过台式电脑与笔记本电脑出货量的总和。 (2)智能手机的用户使用数量正在高速增长。据市场调研机构Gartner信息,2011年全球智能手机的总出货量将会达到4.68亿部,相比2010年实现了57.7%的增长,而谷歌Android操作系统将会在今年之内成为全球最大的智能手机操作系统。另外,全球市场调研机构IDC预计未来5年中国手机市场上,智能手机替代传统功能手机的趋势将日益明显,未来5年中国智能手机市场复合增长率将达到34.1%,人们对IT设备智能化的向往是这一增长率能够实现的主要因素,并且与其他国家相比,中国智能手机市场的发展空间更加广阔。 (3)操作系统格局预测:Android有望成为智能手机市场主导力量 搭载Android操作系统的智能手机目前已经成为市场上最炙手可热的智能产品。来自美国市场研究机构Gartner的数据显示,Android操作系统所占的市场份额从2008年的0.5%急剧增长到2011年的15.94%。开放的源代码和零成本已经让Android在全世界范围内受到青睐并迅速获得了主要手机厂商和数百万软件开发者的支持,Gartner预计,未来Android系统的市场份额有望超过其他操作系统,从而成为全球第一大智能手机操作系统。 2.安卓手机介绍 安卓手机指的是用Android操作系统的手机。安卓(Android)是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。 同样都是手机上面用的智能系统,安卓的系统是新生系统,界面更为华丽,开源性更强,当然因为是新生系统,所以在第三方软件方面暂时还不太多。因此,安卓应用程序的需求还是很迫切的。 3.软件人才需求 据业内统计,目前国内的Android研发人才缺口至少30万。由于目前Android技术较新,无论是相关书籍、培训还是大学教育,都处于初级阶段,因此Android人才短期将供不应求。从长期来看,随着各种移动应用和手机游戏等内容需求日益增加,也将激励大中小型手机应用开发商加大对Android应用的开发力度,因此Android人才的就业前景也非常广泛。 综上所述,在这样的背景下,安卓有很强的生命力。同时,作为一个新生的系统,其应用程序目前并不多,安卓应用程序的需求还是很迫切的,安卓研发人才的缺口还很大。这些都促进了我们学习开发安卓应用程序。 1.2开发环境 安卓应用程序开发环境如下: ①jdk1.8 ②android studio 4.0 ③Android SDK 二 安卓应用程序开发理论与方法 ButterKnife ButterKnife 是一个专注于 Android 系统的 View 注入框架,以前总是要写很多 findViewById 来找到 View 对象,有了 ButterKnife 可以很轻松地省去这些步骤。使用 ButterKnife 对性能基本没有损失,因为 ButterKnife 用到的注解并不是在运行时反射的,而是在编译的时候生成新的 class。项目集成起来特别方便,使用起来也特别简单。 ButterKnife 的优势: 强大的 View 绑定和 Click 事件处理功能,简化代码,提升开发效率 方便地处理 Adapter 里的 ViewHolder 绑定问题 运行时不会影响 APP 效率,使用配置方便 代码清晰,可读性强 SharedPreferences SharedPreferences 是使用键值对的方式来存储数据的。当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且 SharedPreferences 还支持多种不同的数据类型存储。 SQLite + OrmLite SQLite 是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 KB 的内存就足够了,因而特别适合在移动设备上使用。SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务,所以只要以前是用过其他的关系型数据库,就可以很快地上手 SQLite。 ORM(全称 Object Relation Mapping)叫做对象关系映射,是一种程序设计技术,用于实现面向对象编程语言中不同类型系统的数据之间的转换。它可以直接将 Bean 文件转换成数据库中的表,Bean 中的属性就是表的列,它将繁琐的数据库操作封装成一个 Dao 类,使用 Dao 类和 Bean 可以直接对数据库进行操作,大多数的方法参数只有一个 Bean 对象。 多线程编程 Handler + Message Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是使用 Handler 的 sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到 Handler 的 handleMessage()方法中。 Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。除了 what 字段,Message 还可以使用 arg1 和 arg2 字段来携带一些整型数据,使用 obj 字段携带一个 Object 对象。 Glide Glide 是一款快速高效的开源 Android 媒体管理和图片加载框架,它将媒体解码、内存和磁盘缓存以及资源池打包成一个简单易用的界面。 Glide 支持抓取、解码和显示视频图片、图像和动态 gif。Glide 包括一个灵活的 API,允许开发人员插入几乎任何网络堆栈。默认情况下,Glide 使用了一个定制的基于 HttpUrlConnection 的堆栈,但也包含了可插入谷歌的 Volley 项目或 Square 的 OkHttp 库的实用程序库。 Glide 的主要功能是尽可能平滑快速地滚动任何类型的图像列表,但它也适用于几乎任何需要获取、调整大小和显示远程图像的情况。 RecyclerView 控件 RecyclerView 是一个增强版的 ListView,不仅可以轻松实现和 ListView 同样的效果,还优化了 ListView 中存在的各种不足之处。同时 RecyclerView 支持横向滚动和瀑布流布局 Fragment + ViewPager Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。它和 Activity 同样都能包含布局,同样都有自己的生命周期。甚至可以理解成一个迷你的 Activity。 ViewPager 是 android 扩展包 v4 包中的类,这个类可以让用户左右切换当前的 view。ViewPager 类直接继承了 ViewGroup 类,因此它一个容器类,可以添加其他的 View 类 ViewPager 类需要一个 PagerAdapter 适配器类给它提供数据(类似 RecyclerView)。 ViewPager 经常和 Fragment 一起使用,并且官方还提供了专门的 FragmentPagerAdapter 类供 ViewPager 使用。 三 记事本应用程序的设计与实现 3.1 拟解决的问题及目标 一个简单的记事本应用,在人们繁忙的时候更快速的记笔记,程序要实现的目标有如下几个: 登录注册 笔记顶置 开始游戏笔记增删查改 3.2 总体设计 1、记事本操作流程 先注册一个账号,登录进去,可以添加笔记,编辑笔记,顶置笔记,查找笔记 3.3 详细设计与编码实现 记事本界面 注册界面 新建笔记界面 编辑界面 个人信息界面 核心代码如下: RegisterActivity类 public class RegisterActivity extends AppCompatActivity { @BindView(R.id.btn_register) Button btnRegister; @BindView(R.id.btn_reset) Button btnReset; @BindView(R.id.check_hide_pwd_reg) CheckBox checkHidePwdReg; @BindView(R.id.check_hide_pwd_reg2) CheckBox checkHidePwdReg2; @BindView(R.id.edit_username_reg) EditText editUsernameReg; @BindView(R.id.edit_confirm_pwd_reg) EditText editConfirmPwdReg; @BindView(R.id.edit_email_reg) EditText editEmailReg; @BindView(R.id.edit_password_reg) EditText editPasswordReg; SharedPreferenceUtil spu; private static final String TAG = "RegisterActivity"; private UserDao userDao; private String textUserName; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); } @OnClick({R.id.btn_register, R.id.btn_reset, R.id.check_hide_pwd_reg, R.id.check_hide_pwd_reg2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_register: // 检验非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检验密码 if (comparePwd()) { // 检查邮箱格式 if (checkEmail()) { // 检查邮箱是否可用 if (checkOnlyEmail()) { insertUserIntoDB(); queryAll(); Intent intent = new Intent(RegisterActivity.this, MainActivity.class); intent.putExtra(Constant.HAS_REGISTERED, true); startActivity(intent); finish(); } else { Toast.makeText(this, "邮箱已经被使用", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset: editUsernameReg.setText(""); editPasswordReg.setText(""); editConfirmPwdReg.setText(""); editEmailReg.setText(""); break; case R.id.check_hide_pwd_reg: if (checkHidePwdReg.isChecked()) { // 将密码显示出来 editPasswordReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordReg.setSelection(editPasswordReg.getText().toString().length()); break; case R.id.check_hide_pwd_reg2: if (checkHidePwdReg2.isChecked()) { // 将密码显示出来 editConfirmPwdReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdReg.setSelection(editConfirmPwdReg.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editUsernameReg.getText().toString()) && !"".equals(editPasswordReg.getText().toString()) && !"".equals(editConfirmPwdReg.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textUserName = editUsernameReg.getText().toString(); textPassword = editPasswordReg.getText().toString(); textConfirmPwd = editConfirmPwdReg.getText().toString(); textEmail = editEmailReg.getText().toString(); } /** * 检查邮箱是否可用 * * @return */ public boolean checkOnlyEmail() { List userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100" /> 目录 一 安卓应用程序开发背景3 1.1开发背景3 1.2开发环境4 二 安卓应用程序开发理论与方法4 三 记事本应用程序的设计与实现5 3.1 拟解决的问题及目标5 3.2 总体设计6 3.3 详细设计与编码实现6 四 总结23 一 安卓应用程序开发背景 1.1开发背景 1.智能手机的市场 (1)功能多样化的智能手机挑战全球PC出货量 移动互联网时代的来临,直接促进了搭载智能操作系统、具有强大扩展性的智能手机、平板电脑等移动终端产业的蓬勃发展。来自美国最大的风险投资机构KPCB的数据显示,全球智能手机出货量正在以远高于台式电脑、笔记本电脑出货量的速度快速增长,该机构预计2011年全球智能手机出货量将达到4.13亿,超过台式电脑与笔记本电脑出货量的总和。 (2)智能手机的用户使用数量正在高速增长。据市场调研机构Gartner信息,2011年全球智能手机的总出货量将会达到4.68亿部,相比2010年实现了57.7%的增长,而谷歌Android操作系统将会在今年之内成为全球最大的智能手机操作系统。另外,全球市场调研机构IDC预计未来5年中国手机市场上,智能手机替代传统功能手机的趋势将日益明显,未来5年中国智能手机市场复合增长率将达到34.1%,人们对IT设备智能化的向往是这一增长率能够实现的主要因素,并且与其他国家相比,中国智能手机市场的发展空间更加广阔。 (3)操作系统格局预测:Android有望成为智能手机市场主导力量 搭载Android操作系统的智能手机目前已经成为市场上最炙手可热的智能产品。来自美国市场研究机构Gartner的数据显示,Android操作系统所占的市场份额从2008年的0.5%急剧增长到2011年的15.94%。开放的源代码和零成本已经让Android在全世界范围内受到青睐并迅速获得了主要手机厂商和数百万软件开发者的支持,Gartner预计,未来Android系统的市场份额有望超过其他操作系统,从而成为全球第一大智能手机操作系统。 2.安卓手机介绍 安卓手机指的是用Android操作系统的手机。安卓(Android)是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。 同样都是手机上面用的智能系统,安卓的系统是新生系统,界面更为华丽,开源性更强,当然因为是新生系统,所以在第三方软件方面暂时还不太多。因此,安卓应用程序的需求还是很迫切的。 3.软件人才需求 据业内统计,目前国内的Android研发人才缺口至少30万。由于目前Android技术较新,无论是相关书籍、培训还是大学教育,都处于初级阶段,因此Android人才短期将供不应求。从长期来看,随着各种移动应用和手机游戏等内容需求日益增加,也将激励大中小型手机应用开发商加大对Android应用的开发力度,因此Android人才的就业前景也非常广泛。 综上所述,在这样的背景下,安卓有很强的生命力。同时,作为一个新生的系统,其应用程序目前并不多,安卓应用程序的需求还是很迫切的,安卓研发人才的缺口还很大。这些都促进了我们学习开发安卓应用程序。 1.2开发环境 安卓应用程序开发环境如下: ①jdk1.8 ②android studio 4.0 ③Android SDK 二 安卓应用程序开发理论与方法 ButterKnife ButterKnife 是一个专注于 Android 系统的 View 注入框架,以前总是要写很多 findViewById 来找到 View 对象,有了 ButterKnife 可以很轻松地省去这些步骤。使用 ButterKnife 对性能基本没有损失,因为 ButterKnife 用到的注解并不是在运行时反射的,而是在编译的时候生成新的 class。项目集成起来特别方便,使用起来也特别简单。 ButterKnife 的优势: 强大的 View 绑定和 Click 事件处理功能,简化代码,提升开发效率 方便地处理 Adapter 里的 ViewHolder 绑定问题 运行时不会影响 APP 效率,使用配置方便 代码清晰,可读性强 SharedPreferences SharedPreferences 是使用键值对的方式来存储数据的。当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且 SharedPreferences 还支持多种不同的数据类型存储。 SQLite + OrmLite SQLite 是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 KB 的内存就足够了,因而特别适合在移动设备上使用。SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务,所以只要以前是用过其他的关系型数据库,就可以很快地上手 SQLite。 ORM(全称 Object Relation Mapping)叫做对象关系映射,是一种程序设计技术,用于实现面向对象编程语言中不同类型系统的数据之间的转换。它可以直接将 Bean 文件转换成数据库中的表,Bean 中的属性就是表的列,它将繁琐的数据库操作封装成一个 Dao 类,使用 Dao 类和 Bean 可以直接对数据库进行操作,大多数的方法参数只有一个 Bean 对象。 多线程编程 Handler + Message Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是使用 Handler 的 sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到 Handler 的 handleMessage()方法中。 Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。除了 what 字段,Message 还可以使用 arg1 和 arg2 字段来携带一些整型数据,使用 obj 字段携带一个 Object 对象。 Glide Glide 是一款快速高效的开源 Android 媒体管理和图片加载框架,它将媒体解码、内存和磁盘缓存以及资源池打包成一个简单易用的界面。 Glide 支持抓取、解码和显示视频图片、图像和动态 gif。Glide 包括一个灵活的 API,允许开发人员插入几乎任何网络堆栈。默认情况下,Glide 使用了一个定制的基于 HttpUrlConnection 的堆栈,但也包含了可插入谷歌的 Volley 项目或 Square 的 OkHttp 库的实用程序库。 Glide 的主要功能是尽可能平滑快速地滚动任何类型的图像列表,但它也适用于几乎任何需要获取、调整大小和显示远程图像的情况。 RecyclerView 控件 RecyclerView 是一个增强版的 ListView,不仅可以轻松实现和 ListView 同样的效果,还优化了 ListView 中存在的各种不足之处。同时 RecyclerView 支持横向滚动和瀑布流布局 Fragment + ViewPager Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。它和 Activity 同样都能包含布局,同样都有自己的生命周期。甚至可以理解成一个迷你的 Activity。 ViewPager 是 android 扩展包 v4 包中的类,这个类可以让用户左右切换当前的 view。ViewPager 类直接继承了 ViewGroup 类,因此它一个容器类,可以添加其他的 View 类 ViewPager 类需要一个 PagerAdapter 适配器类给它提供数据(类似 RecyclerView)。 ViewPager 经常和 Fragment 一起使用,并且官方还提供了专门的 FragmentPagerAdapter 类供 ViewPager 使用。 三 记事本应用程序的设计与实现 3.1 拟解决的问题及目标 一个简单的记事本应用,在人们繁忙的时候更快速的记笔记,程序要实现的目标有如下几个: 登录注册 笔记顶置 开始游戏笔记增删查改 3.2 总体设计 1、记事本操作流程 先注册一个账号,登录进去,可以添加笔记,编辑笔记,顶置笔记,查找笔记 3.3 详细设计与编码实现 记事本界面 注册界面 新建笔记界面 编辑界面 个人信息界面 核心代码如下: RegisterActivity类 public class RegisterActivity extends AppCompatActivity { @BindView(R.id.btn_register) Button btnRegister; @BindView(R.id.btn_reset) Button btnReset; @BindView(R.id.check_hide_pwd_reg) CheckBox checkHidePwdReg; @BindView(R.id.check_hide_pwd_reg2) CheckBox checkHidePwdReg2; @BindView(R.id.edit_username_reg) EditText editUsernameReg; @BindView(R.id.edit_confirm_pwd_reg) EditText editConfirmPwdReg; @BindView(R.id.edit_email_reg) EditText editEmailReg; @BindView(R.id.edit_password_reg) EditText editPasswordReg; SharedPreferenceUtil spu; private static final String TAG = "RegisterActivity"; private UserDao userDao; private String textUserName; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); } @OnClick({R.id.btn_register, R.id.btn_reset, R.id.check_hide_pwd_reg, R.id.check_hide_pwd_reg2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_register: // 检验非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检验密码 if (comparePwd()) { // 检查邮箱格式 if (checkEmail()) { // 检查邮箱是否可用 if (checkOnlyEmail()) { insertUserIntoDB(); queryAll(); Intent intent = new Intent(RegisterActivity.this, MainActivity.class); intent.putExtra(Constant.HAS_REGISTERED, true); startActivity(intent); finish(); } else { Toast.makeText(this, "邮箱已经被使用", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset: editUsernameReg.setText(""); editPasswordReg.setText(""); editConfirmPwdReg.setText(""); editEmailReg.setText(""); break; case R.id.check_hide_pwd_reg: if (checkHidePwdReg.isChecked()) { // 将密码显示出来 editPasswordReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordReg.setSelection(editPasswordReg.getText().toString().length()); break; case R.id.check_hide_pwd_reg2: if (checkHidePwdReg2.isChecked()) { // 将密码显示出来 editConfirmPwdReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdReg.setSelection(editConfirmPwdReg.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editUsernameReg.getText().toString()) && !"".equals(editPasswordReg.getText().toString()) && !"".equals(editConfirmPwdReg.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textUserName = editUsernameReg.getText().toString(); textPassword = editPasswordReg.getText().toString(); textConfirmPwd = editConfirmPwdReg.getText().toString(); textEmail = editEmailReg.getText().toString(); } /** * 检查邮箱是否可用 * * @return */ public boolean checkOnlyEmail() { List userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100[/caption]userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100" title="目录 一 安卓应用程序开发背景3 1.1开发背景3 1.2开发环境4 二 安卓应用程序开发理论与方法4 三 记事本应用程序的设计与实现5 3.1 拟解决的问题及目标5 3.2 总体设计6 3.3 详细设计与编码实现6 四 总结23 一 安卓应用程序开发背景 1.1开发背景 1.智能手机的市场 (1)功能多样化的智能手机挑战全球PC出货量 移动互联网时代的来临,直接促进了搭载智能操作系统、具有强大扩展性的智能手机、平板电脑等移动终端产业的蓬勃发展。来自美国最大的风险投资机构KPCB的数据显示,全球智能手机出货量正在以远高于台式电脑、笔记本电脑出货量的速度快速增长,该机构预计2011年全球智能手机出货量将达到4.13亿,超过台式电脑与笔记本电脑出货量的总和。 (2)智能手机的用户使用数量正在高速增长。据市场调研机构Gartner信息,2011年全球智能手机的总出货量将会达到4.68亿部,相比2010年实现了57.7%的增长,而谷歌Android操作系统将会在今年之内成为全球最大的智能手机操作系统。另外,全球市场调研机构IDC预计未来5年中国手机市场上,智能手机替代传统功能手机的趋势将日益明显,未来5年中国智能手机市场复合增长率将达到34.1%,人们对IT设备智能化的向往是这一增长率能够实现的主要因素,并且与其他国家相比,中国智能手机市场的发展空间更加广阔。 (3)操作系统格局预测:Android有望成为智能手机市场主导力量 搭载Android操作系统的智能手机目前已经成为市场上最炙手可热的智能产品。来自美国市场研究机构Gartner的数据显示,Android操作系统所占的市场份额从2008年的0.5%急剧增长到2011年的15.94%。开放的源代码和零成本已经让Android在全世界范围内受到青睐并迅速获得了主要手机厂商和数百万软件开发者的支持,Gartner预计,未来Android系统的市场份额有望超过其他操作系统,从而成为全球第一大智能手机操作系统。 2.安卓手机介绍 安卓手机指的是用Android操作系统的手机。安卓(Android)是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。 同样都是手机上面用的智能系统,安卓的系统是新生系统,界面更为华丽,开源性更强,当然因为是新生系统,所以在第三方软件方面暂时还不太多。因此,安卓应用程序的需求还是很迫切的。 3.软件人才需求 据业内统计,目前国内的Android研发人才缺口至少30万。由于目前Android技术较新,无论是相关书籍、培训还是大学教育,都处于初级阶段,因此Android人才短期将供不应求。从长期来看,随着各种移动应用和手机游戏等内容需求日益增加,也将激励大中小型手机应用开发商加大对Android应用的开发力度,因此Android人才的就业前景也非常广泛。 综上所述,在这样的背景下,安卓有很强的生命力。同时,作为一个新生的系统,其应用程序目前并不多,安卓应用程序的需求还是很迫切的,安卓研发人才的缺口还很大。这些都促进了我们学习开发安卓应用程序。 1.2开发环境 安卓应用程序开发环境如下: ①jdk1.8 ②android studio 4.0 ③Android SDK 二 安卓应用程序开发理论与方法 ButterKnife ButterKnife 是一个专注于 Android 系统的 View 注入框架,以前总是要写很多 findViewById 来找到 View 对象,有了 ButterKnife 可以很轻松地省去这些步骤。使用 ButterKnife 对性能基本没有损失,因为 ButterKnife 用到的注解并不是在运行时反射的,而是在编译的时候生成新的 class。项目集成起来特别方便,使用起来也特别简单。 ButterKnife 的优势: 强大的 View 绑定和 Click 事件处理功能,简化代码,提升开发效率 方便地处理 Adapter 里的 ViewHolder 绑定问题 运行时不会影响 APP 效率,使用配置方便 代码清晰,可读性强 SharedPreferences SharedPreferences 是使用键值对的方式来存储数据的。当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且 SharedPreferences 还支持多种不同的数据类型存储。 SQLite + OrmLite SQLite 是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 KB 的内存就足够了,因而特别适合在移动设备上使用。SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务,所以只要以前是用过其他的关系型数据库,就可以很快地上手 SQLite。 ORM(全称 Object Relation Mapping)叫做对象关系映射,是一种程序设计技术,用于实现面向对象编程语言中不同类型系统的数据之间的转换。它可以直接将 Bean 文件转换成数据库中的表,Bean 中的属性就是表的列,它将繁琐的数据库操作封装成一个 Dao 类,使用 Dao 类和 Bean 可以直接对数据库进行操作,大多数的方法参数只有一个 Bean 对象。 多线程编程 Handler + Message Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是使用 Handler 的 sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到 Handler 的 handleMessage()方法中。 Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。除了 what 字段,Message 还可以使用 arg1 和 arg2 字段来携带一些整型数据,使用 obj 字段携带一个 Object 对象。 Glide Glide 是一款快速高效的开源 Android 媒体管理和图片加载框架,它将媒体解码、内存和磁盘缓存以及资源池打包成一个简单易用的界面。 Glide 支持抓取、解码和显示视频图片、图像和动态 gif。Glide 包括一个灵活的 API,允许开发人员插入几乎任何网络堆栈。默认情况下,Glide 使用了一个定制的基于 HttpUrlConnection 的堆栈,但也包含了可插入谷歌的 Volley 项目或 Square 的 OkHttp 库的实用程序库。 Glide 的主要功能是尽可能平滑快速地滚动任何类型的图像列表,但它也适用于几乎任何需要获取、调整大小和显示远程图像的情况。 RecyclerView 控件 RecyclerView 是一个增强版的 ListView,不仅可以轻松实现和 ListView 同样的效果,还优化了 ListView 中存在的各种不足之处。同时 RecyclerView 支持横向滚动和瀑布流布局 Fragment + ViewPager Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。它和 Activity 同样都能包含布局,同样都有自己的生命周期。甚至可以理解成一个迷你的 Activity。 ViewPager 是 android 扩展包 v4 包中的类,这个类可以让用户左右切换当前的 view。ViewPager 类直接继承了 ViewGroup 类,因此它一个容器类,可以添加其他的 View 类 ViewPager 类需要一个 PagerAdapter 适配器类给它提供数据(类似 RecyclerView)。 ViewPager 经常和 Fragment 一起使用,并且官方还提供了专门的 FragmentPagerAdapter 类供 ViewPager 使用。 三 记事本应用程序的设计与实现 3.1 拟解决的问题及目标 一个简单的记事本应用,在人们繁忙的时候更快速的记笔记,程序要实现的目标有如下几个: 登录注册 笔记顶置 开始游戏笔记增删查改 3.2 总体设计 1、记事本操作流程 先注册一个账号,登录进去,可以添加笔记,编辑笔记,顶置笔记,查找笔记 3.3 详细设计与编码实现 记事本界面 注册界面 新建笔记界面 编辑界面 个人信息界面 核心代码如下: RegisterActivity类 public class RegisterActivity extends AppCompatActivity { @BindView(R.id.btn_register) Button btnRegister; @BindView(R.id.btn_reset) Button btnReset; @BindView(R.id.check_hide_pwd_reg) CheckBox checkHidePwdReg; @BindView(R.id.check_hide_pwd_reg2) CheckBox checkHidePwdReg2; @BindView(R.id.edit_username_reg) EditText editUsernameReg; @BindView(R.id.edit_confirm_pwd_reg) EditText editConfirmPwdReg; @BindView(R.id.edit_email_reg) EditText editEmailReg; @BindView(R.id.edit_password_reg) EditText editPasswordReg; SharedPreferenceUtil spu; private static final String TAG = "RegisterActivity"; private UserDao userDao; private String textUserName; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); } @OnClick({R.id.btn_register, R.id.btn_reset, R.id.check_hide_pwd_reg, R.id.check_hide_pwd_reg2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_register: // 检验非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检验密码 if (comparePwd()) { // 检查邮箱格式 if (checkEmail()) { // 检查邮箱是否可用 if (checkOnlyEmail()) { insertUserIntoDB(); queryAll(); Intent intent = new Intent(RegisterActivity.this, MainActivity.class); intent.putExtra(Constant.HAS_REGISTERED, true); startActivity(intent); finish(); } else { Toast.makeText(this, "邮箱已经被使用", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset: editUsernameReg.setText(""); editPasswordReg.setText(""); editConfirmPwdReg.setText(""); editEmailReg.setText(""); break; case R.id.check_hide_pwd_reg: if (checkHidePwdReg.isChecked()) { // 将密码显示出来 editPasswordReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordReg.setSelection(editPasswordReg.getText().toString().length()); break; case R.id.check_hide_pwd_reg2: if (checkHidePwdReg2.isChecked()) { // 将密码显示出来 editConfirmPwdReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdReg.setSelection(editConfirmPwdReg.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editUsernameReg.getText().toString()) && !"".equals(editPasswordReg.getText().toString()) && !"".equals(editConfirmPwdReg.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textUserName = editUsernameReg.getText().toString(); textPassword = editPasswordReg.getText().toString(); textConfirmPwd = editConfirmPwdReg.getText().toString(); textEmail = editEmailReg.getText().toString(); } /** * 检查邮箱是否可用 * * @return */ public boolean checkOnlyEmail() { List userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100" /> 目录 一 安卓应用程序开发背景3 1.1开发背景3 1.2开发环境4 二 安卓应用程序开发理论与方法4 三 记事本应用程序的设计与实现5 3.1 拟解决的问题及目标5 3.2 总体设计6 3.3 详细设计与编码实现6 四 总结23 一 安卓应用程序开发背景 1.1开发背景 1.智能手机的市场 (1)功能多样化的智能手机挑战全球PC出货量 移动互联网时代的来临,直接促进了搭载智能操作系统、具有强大扩展性的智能手机、平板电脑等移动终端产业的蓬勃发展。来自美国最大的风险投资机构KPCB的数据显示,全球智能手机出货量正在以远高于台式电脑、笔记本电脑出货量的速度快速增长,该机构预计2011年全球智能手机出货量将达到4.13亿,超过台式电脑与笔记本电脑出货量的总和。 (2)智能手机的用户使用数量正在高速增长。据市场调研机构Gartner信息,2011年全球智能手机的总出货量将会达到4.68亿部,相比2010年实现了57.7%的增长,而谷歌Android操作系统将会在今年之内成为全球最大的智能手机操作系统。另外,全球市场调研机构IDC预计未来5年中国手机市场上,智能手机替代传统功能手机的趋势将日益明显,未来5年中国智能手机市场复合增长率将达到34.1%,人们对IT设备智能化的向往是这一增长率能够实现的主要因素,并且与其他国家相比,中国智能手机市场的发展空间更加广阔。 (3)操作系统格局预测:Android有望成为智能手机市场主导力量 搭载Android操作系统的智能手机目前已经成为市场上最炙手可热的智能产品。来自美国市场研究机构Gartner的数据显示,Android操作系统所占的市场份额从2008年的0.5%急剧增长到2011年的15.94%。开放的源代码和零成本已经让Android在全世界范围内受到青睐并迅速获得了主要手机厂商和数百万软件开发者的支持,Gartner预计,未来Android系统的市场份额有望超过其他操作系统,从而成为全球第一大智能手机操作系统。 2.安卓手机介绍 安卓手机指的是用Android操作系统的手机。安卓(Android)是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。 同样都是手机上面用的智能系统,安卓的系统是新生系统,界面更为华丽,开源性更强,当然因为是新生系统,所以在第三方软件方面暂时还不太多。因此,安卓应用程序的需求还是很迫切的。 3.软件人才需求 据业内统计,目前国内的Android研发人才缺口至少30万。由于目前Android技术较新,无论是相关书籍、培训还是大学教育,都处于初级阶段,因此Android人才短期将供不应求。从长期来看,随着各种移动应用和手机游戏等内容需求日益增加,也将激励大中小型手机应用开发商加大对Android应用的开发力度,因此Android人才的就业前景也非常广泛。 综上所述,在这样的背景下,安卓有很强的生命力。同时,作为一个新生的系统,其应用程序目前并不多,安卓应用程序的需求还是很迫切的,安卓研发人才的缺口还很大。这些都促进了我们学习开发安卓应用程序。 1.2开发环境 安卓应用程序开发环境如下: ①jdk1.8 ②android studio 4.0 ③Android SDK 二 安卓应用程序开发理论与方法 ButterKnife ButterKnife 是一个专注于 Android 系统的 View 注入框架,以前总是要写很多 findViewById 来找到 View 对象,有了 ButterKnife 可以很轻松地省去这些步骤。使用 ButterKnife 对性能基本没有损失,因为 ButterKnife 用到的注解并不是在运行时反射的,而是在编译的时候生成新的 class。项目集成起来特别方便,使用起来也特别简单。 ButterKnife 的优势: 强大的 View 绑定和 Click 事件处理功能,简化代码,提升开发效率 方便地处理 Adapter 里的 ViewHolder 绑定问题 运行时不会影响 APP 效率,使用配置方便 代码清晰,可读性强 SharedPreferences SharedPreferences 是使用键值对的方式来存储数据的。当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且 SharedPreferences 还支持多种不同的数据类型存储。 SQLite + OrmLite SQLite 是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 KB 的内存就足够了,因而特别适合在移动设备上使用。SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务,所以只要以前是用过其他的关系型数据库,就可以很快地上手 SQLite。 ORM(全称 Object Relation Mapping)叫做对象关系映射,是一种程序设计技术,用于实现面向对象编程语言中不同类型系统的数据之间的转换。它可以直接将 Bean 文件转换成数据库中的表,Bean 中的属性就是表的列,它将繁琐的数据库操作封装成一个 Dao 类,使用 Dao 类和 Bean 可以直接对数据库进行操作,大多数的方法参数只有一个 Bean 对象。 多线程编程 Handler + Message Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是使用 Handler 的 sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到 Handler 的 handleMessage()方法中。 Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。除了 what 字段,Message 还可以使用 arg1 和 arg2 字段来携带一些整型数据,使用 obj 字段携带一个 Object 对象。 Glide Glide 是一款快速高效的开源 Android 媒体管理和图片加载框架,它将媒体解码、内存和磁盘缓存以及资源池打包成一个简单易用的界面。 Glide 支持抓取、解码和显示视频图片、图像和动态 gif。Glide 包括一个灵活的 API,允许开发人员插入几乎任何网络堆栈。默认情况下,Glide 使用了一个定制的基于 HttpUrlConnection 的堆栈,但也包含了可插入谷歌的 Volley 项目或 Square 的 OkHttp 库的实用程序库。 Glide 的主要功能是尽可能平滑快速地滚动任何类型的图像列表,但它也适用于几乎任何需要获取、调整大小和显示远程图像的情况。 RecyclerView 控件 RecyclerView 是一个增强版的 ListView,不仅可以轻松实现和 ListView 同样的效果,还优化了 ListView 中存在的各种不足之处。同时 RecyclerView 支持横向滚动和瀑布流布局 Fragment + ViewPager Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。它和 Activity 同样都能包含布局,同样都有自己的生命周期。甚至可以理解成一个迷你的 Activity。 ViewPager 是 android 扩展包 v4 包中的类,这个类可以让用户左右切换当前的 view。ViewPager 类直接继承了 ViewGroup 类,因此它一个容器类,可以添加其他的 View 类 ViewPager 类需要一个 PagerAdapter 适配器类给它提供数据(类似 RecyclerView)。 ViewPager 经常和 Fragment 一起使用,并且官方还提供了专门的 FragmentPagerAdapter 类供 ViewPager 使用。 三 记事本应用程序的设计与实现 3.1 拟解决的问题及目标 一个简单的记事本应用,在人们繁忙的时候更快速的记笔记,程序要实现的目标有如下几个: 登录注册 笔记顶置 开始游戏笔记增删查改 3.2 总体设计 1、记事本操作流程 先注册一个账号,登录进去,可以添加笔记,编辑笔记,顶置笔记,查找笔记 3.3 详细设计与编码实现 记事本界面 注册界面 新建笔记界面 编辑界面 个人信息界面 核心代码如下: RegisterActivity类 public class RegisterActivity extends AppCompatActivity { @BindView(R.id.btn_register) Button btnRegister; @BindView(R.id.btn_reset) Button btnReset; @BindView(R.id.check_hide_pwd_reg) CheckBox checkHidePwdReg; @BindView(R.id.check_hide_pwd_reg2) CheckBox checkHidePwdReg2; @BindView(R.id.edit_username_reg) EditText editUsernameReg; @BindView(R.id.edit_confirm_pwd_reg) EditText editConfirmPwdReg; @BindView(R.id.edit_email_reg) EditText editEmailReg; @BindView(R.id.edit_password_reg) EditText editPasswordReg; SharedPreferenceUtil spu; private static final String TAG = "RegisterActivity"; private UserDao userDao; private String textUserName; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); } @OnClick({R.id.btn_register, R.id.btn_reset, R.id.check_hide_pwd_reg, R.id.check_hide_pwd_reg2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_register: // 检验非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检验密码 if (comparePwd()) { // 检查邮箱格式 if (checkEmail()) { // 检查邮箱是否可用 if (checkOnlyEmail()) { insertUserIntoDB(); queryAll(); Intent intent = new Intent(RegisterActivity.this, MainActivity.class); intent.putExtra(Constant.HAS_REGISTERED, true); startActivity(intent); finish(); } else { Toast.makeText(this, "邮箱已经被使用", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset: editUsernameReg.setText(""); editPasswordReg.setText(""); editConfirmPwdReg.setText(""); editEmailReg.setText(""); break; case R.id.check_hide_pwd_reg: if (checkHidePwdReg.isChecked()) { // 将密码显示出来 editPasswordReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordReg.setSelection(editPasswordReg.getText().toString().length()); break; case R.id.check_hide_pwd_reg2: if (checkHidePwdReg2.isChecked()) { // 将密码显示出来 editConfirmPwdReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdReg.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdReg.setSelection(editConfirmPwdReg.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editUsernameReg.getText().toString()) && !"".equals(editPasswordReg.getText().toString()) && !"".equals(editConfirmPwdReg.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textUserName = editUsernameReg.getText().toString(); textPassword = editPasswordReg.getText().toString(); textConfirmPwd = editConfirmPwdReg.getText().toString(); textEmail = editEmailReg.getText().toString(); } /** * 检查邮箱是否可用 * * @return */ public boolean checkOnlyEmail() { List userBeans = userDao.queryForWhat("email", textEmail); return userBeans.size() == 0; } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 向数据库表插入数据 */ public void insertUserIntoDB() { UserBean userBean = new UserBean(textUserName, textPassword, textEmail); userDao.insert(userBean); // 同时存到SP中 spu.putString(Constant.USER_NAME, textUserName); spu.putString(Constant.PASSWORD, textPassword); } /** * 查询表中所有数据 */ public void queryAll() { List userBeans = userDao.queryAll(); for (int i = 0; i < userBeans.size(); i++) { Log.d(TAG, "queryAll: " + userBeans.get(i).toString()); } } } HomeActivity类 public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.btn_top) RadioButton btnTop; @BindView(R.id.btn_add) RadioButton btnAdd; @BindView(R.id.btn_all) RadioButton btnAll; @BindView(R.id.dock_radio_group) RadioGroup dockRadioGroup; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.nav_view) NavigationView navView; private static final String TAG = "HomeActivity"; ActionBar actionBar; Fragment fragment; FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); SharedPreferenceUtil spu; private UserDao userDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); userDao = new UserDao(this); spu = SharedPreferenceUtil.getInstance(this); initView(); } /** * 初始化控件 */ public void initView() { // 工具栏 toolbar.setTitle(R.string.app_name); setTitleCenter(toolbar); setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.icon_setting); } // 抽屉 ViewGroup.LayoutParams params = navView.getLayoutParams(); params.width = getResources().getDisplayMetrics().widthPixels / 2; navView.setLayoutParams(params); navView.setNavigationItemSelectedListener(this); // 抽屉中的header View headerView = navView.getHeaderView(0); TextView textUserName = headerView.findViewById(R.id.header_user_name); TextView textEmail = headerView.findViewById(R.id.header_email); textUserName.setText(spu.getString(Constant.USER_NAME)); textEmail.setText(getEmail()); // 默认加载置顶Fragment fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); } /** * 单选按钮监听器 用来切换Fragment * * @param view * @param isChanged */ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top}) public void onCheckedChanged(CompoundButton view, boolean isChanged) { transaction = manager.beginTransaction(); switch (view.getId()) { case R.id.btn_top: if (isChanged) { fragment = new TopFragment(); transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG); transaction.commit(); Constant.PAGE_STATE = "top"; } break; case R.id.btn_add: if (isChanged) { fragment = new AddFragment(); transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG); transaction.commit(); } break; case R.id.btn_all: if (isChanged) { fragment = new AllFragment(); transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG); transaction.commit(); Constant.PAGE_STATE = "all"; } break; default: break; } } /** * 获得登录用户的邮箱 * * @return */ public String getEmail() { List userBeans = userDao .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD)); return userBeans.get(0).getEmail(); } /** * 抽屉中菜单的点击事件 * * @param item * @return */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.nav_change_pwd: DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_dismiss: DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID)); break; case R.id.nav_exit: spu.putBoolean(Constant.AUTO_LOGIN, false); Intent intent = new Intent(HomeActivity.this, MainActivity.class); startActivity(intent); finish(); break; default: break; } return true; } /** * ToolBar的menu * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); setIconsVisible(menu, true); return true; } /** * 重写ToolBar上菜单点击事件 * 按照条件查找 * * @param item * @return */ @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.search_title: DialogUtil.searchTitleDialog(this); break; case R.id.search_content: DialogUtil.searchContentDialog(this); break; case R.id.search_category: DialogUtil.searchCategoryDialog(this); break; case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); break; default: break; } return true; } /** * ToolBar标题居中 * * @param toolbar */ public void setTitleCenter(Toolbar toolbar) { String title = "title"; final CharSequence originalTitle = toolbar.getTitle(); toolbar.setTitle(title); for (int i = 0; i < toolbar.getChildCount(); i++) { View view = toolbar.getChildAt(i); if (view instanceof TextView) { TextView textView = (TextView) view; if (title.equals(textView.getText())) { textView.setGravity(Gravity.CENTER); Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT); params.gravity = Gravity.CENTER; textView.setLayoutParams(params); } } toolbar.setTitle(originalTitle); } } /** * menu显示图标 * * @param menu * @param flag */ private void setIconsVisible(Menu menu, boolean flag) { // 判断menu是否为空 if (menu != null) { try { // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法 Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); // 暴力访问该方法 method.setAccessible(true); // 调用该方法显示icon method.invoke(menu, flag); } catch (Exception e) { e.printStackTrace(); } } } FindPwdActivity类 public class FindPwdActivity extends AppCompatActivity { @BindView(R.id.btn_confirm_find) Button btnConfirmFind; @BindView(R.id.btn_reset_find) Button btnResetFind; @BindView(R.id.edit_confirm_pwd_find) EditText editConfirmPwdFind; @BindView(R.id.edit_password_find) EditText editPasswordFind; @BindView(R.id.edit_email_find) EditText editEmailFind; @BindView(R.id.check_hide_pwd_find) CheckBox checkHidePwdFind; @BindView(R.id.check_hide_pwd_find2) CheckBox checkHidePwdFind2; private static final String TAG = "FindPwdActivity"; private UserDao userDao; private String textPassword; private String textConfirmPwd; private String textEmail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_find_pwd); ButterKnife.bind(this); userDao = new UserDao(this); } @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_confirm_find: // 检查非空 if (isNotEmpty()) { // 获得用户输入 getEditText(); // 检查邮箱格式 if (checkEmail()) { // 检查两次输入的密码是否一致 if (comparePwd()) { // 更新密码 if (updatePwdFromDB()) { // 跳转登录界面 Intent intent = new Intent(FindPwdActivity.this, MainActivity.class); startActivity(intent); FindPwdActivity.this.finish(); } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_reset_find: // 清空输入 editPasswordFind.setText(""); editConfirmPwdFind.setText(""); editEmailFind.setText(""); break; case R.id.check_hide_pwd_find: if (checkHidePwdFind.isChecked()) { // 将密码显示出来 editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editPasswordFind.setSelection(editPasswordFind.getText().toString().length()); break; case R.id.check_hide_pwd_find2: if (checkHidePwdFind2.isChecked()) { // 将密码显示出来 editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { // 隐藏密码 editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance()); } // 将光标移动到文本最后 editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length()); break; default: break; } } /** * 检验输入非空 * * @return */ public boolean isNotEmpty() { return !"".equals(editPasswordFind.getText().toString()) && !"".equals(editConfirmPwdFind.getText().toString()) && !"".equals(editEmailFind.getText().toString()); } /** * 从控件中得到输入值 */ public void getEditText() { textPassword = editPasswordFind.getText().toString(); textConfirmPwd = editConfirmPwdFind.getText().toString(); textEmail = editEmailFind.getText().toString(); Log.d(TAG, "getEditText: " + textEmail); } /** * 检查邮箱格式 * * @return */ public boolean checkEmail() { Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail); return emailMatcher.matches(); } /** * 验证两次输入的密码是否一致 * * @return */ public boolean comparePwd() { return textPassword.equals(textConfirmPwd); } /** * 修改数据库中的密码 * * @return 邮箱是否存在 */ public boolean updatePwdFromDB() { List userBeans = userDao.queryForWhat("email", textEmail); if (userBeans.size() != 0) { UserBean user = userBeans.get(0); user.setPassword(textPassword); userDao.update(user); return true; } else { Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show(); return false; } } } } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText("SCORE: "+data[0]+"\nBEST: "+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 100[/caption]

protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
initViews();
btn_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
register();
}
});
btn_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
}
private void initViews() {
DBHelper helper = new DBHelper(this);
db = helper.getWritableDatabase();
btn_register = findViewById(R.id.register_btn_register);
btn_back = findViewById(R.id.register_btn_back);
et_username = findViewById(R.id.register_username);
et_password = findViewById(R.id.register_password);
et_repeat = findViewById(R.id.register_password_again);
}
private void register() {
String userName = et_username.getText().toString().trim();
String password = et_password.getText().toString().trim();
String passwordAgain = et_repeat.getText().toString().trim();
if (UIfEmpty.ifEmpty(userName, password, passwordAgain)) {
Toast.makeText(RegisterActivity.this"信息未输入完整", Toast.LENGTH_SHORT).show();
else {
if(password.equals(passwordAgain)) {
ContentValues values = new ContentValues();
values.put("username", userName);
values.put("password", password);
long flag = 0;
flag = db.insert("user"null, values);
if(flag == -1) {
Toast.makeText(RegisterActivity.this"账号已被注册", Toast.LENGTH_SHORT).show();
else {
Toast.makeText(RegisterActivity.this"注册成功", Toast.LENGTH_SHORT).show();
onBackPressed();
}
else {
Toast.makeText(RegisterActivity.this"两次输入的密码不一致", Toast.LENGTH_SHORT).show();
}
}
}
}

首页的主要代码

安卓APP源码和设计报告——仿淘宝水果商城

public View initView() {
View view = View.inflate(mContext, R.layout.fragment_homenull);
lv_home = view.findViewById(R.id.lv_home);
ib_top = view.findViewById(R.id.ib_top);
tv_search_home = view.findViewById(R.id.tv_search_home);
tv_message_home = view.findViewById(R.id.tv_message_home);
initListener();
return view;
}
public void initData() {
super.initData();
ArrayList<Goods> goods = new ArrayList<>();
goods.add(new Goods(2, R.drawable.lll"荔枝""海南", 25.00, 99, "水果店"));
goods.add(new Goods(3, R.drawable.computer"电脑""16英寸", 6599.00, 5, "Apple产品京东自营旗舰店"));
goods.add(new Goods(4, R.drawable.ppp"苹果""红富士", 10.00, 19, "华来水果店"));
goods.add(new Goods(5, R.drawable.xxx"香蕉""海南", 15.00, 18, "水果店"));
goods.add(new Goods(7, R.drawable.kouhong" 口红""正红色", 188.00, 1, "化妆品专营店"));
goods.add(new Goods(8, R.drawable.bamai8"跑车""轿车", 180000, 99999999, "BMW旗舰店"));
GoodsListAdapter adapter = new GoodsListAdapter(mContext, goods);
lv_home.setAdapter(adapter);
}

网络连接请求的主要代码
private void initListener() {
ib_top.setOnClickListener(v -> {
lv_home.smoothScrollToPosition(0);
});
tv_search_home.setOnClickListener(v -> {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.setData(Uri.parse("quanjing.com/feature/de"));
startActivity(intent);
});
}

分类页面的主要代码

安卓APP源码和设计报告——仿淘宝水果商城

public View initView() {
View view = View.inflate(mContext, R.layout.type_homenull);
rg_type = view.findViewById(R.id.rg_type);
initFragment();
initListener();
rg_type.check(R.id.rb_commf1);
return view;
}

public void initData() {
super.initData();
}
private void initFragment() {
fragments new ArrayList<>();
fragments.add(new Jdtuijian()); //推荐分类
fragments.add(new JdShoping());
fragments.add(new Guoji());
}

private BaseFragment getFragment(int position) {
if (fragments != null && fragments.size() > 0) {
BaseFragment baseFragment = fragments.get(position);
return baseFragment;
}
return null;
}
private void switchFragment(Fragment fromfragment, BaseFragment nextfragment) {
if (tempFragment != nextfragment) {
tempFragment = nextfragment;
if (nextfragment != null) {
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
if (!nextfragment.isAdded()) {
if (fromfragment != null) {
transaction.hide(fromfragment);
}
transaction.add(R.id.frameLayout_type, nextfragment).commit();
else {
if (fromfragment != null) {
transaction.hide(fromfragment);
}
transaction.show(nextfragment).commit();
}
}
}
}

分类页面中的超市主要代码

public class HomeAdapter2 extends BaseAdapter {
@Override
public int getCount() {
return imagenames2.length;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
tv_jd_commr1.setText("日用百货");
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.type_grid_item1null);
ImageView iv_icon = view.findViewById(R.id.ic_icon);
TextView tv_name = view.findViewById(R.id.tv_name);
tv_name.setText(imagenames2[position]);
iv_icon.setImageResource(ids2[position]);
return view;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}

分类页面中的推荐分类主要代码

public class HomeAdapter1 extends BaseAdapter {
@Override
public int getCount() {
return imagenames1.length;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
tv_jd_commr1.setText("常用分类");
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.type_grid_item1null);
ImageView iv_icon = (ImageView) view.findViewById(R.id.ic_icon);
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
tv_name.setText(imagenames1[position]);
iv_icon.setImageResource(ids1[position]);
return view;
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}
}

分类页面中的大牌主要代码

public View initView() {
View view = View.inflate(mContext, R.layout.type_gridnull);
gridview_jd_r1 = view.findViewById(R.id.gridview_jd_r1);
tv_jd_commr1 = view.findViewById(R.id.tv_jd_commr1);
gridview_jd_r1.setAdapter(new HomeAdapter3());
return view;
}
public void initData() {
super.initData();
}
public class HomeAdapter3 extends BaseAdapter {
@Override
public int getCount() {
return imagenames3.length;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
tv_jd_commr1.setText("大牌区");
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.type_grid_item1null);
ImageView iv_icon = (ImageView) view.findViewById(R.id.ic_icon);
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
tv_name.setText(imagenames3[position]);
iv_icon.setImageResource(ids3[position]);
return view;
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}
}

发现页面的主要代码

安卓APP源码和设计报告——仿淘宝水果商城

public class CommunityFragment extends BaseFragment {
private ListView shop_list;
@Override
public View initView() {
View view = View.inflate(mContext, R.layout.fragment_communitynull);
shop_list = view.findViewById(R.id.shop_list);
return view;
}
public void initData() {
super.initData();
ArrayList<Shop> shops = new ArrayList<>();
Goods s1_goods1 = new Goods(R.drawable.ppp"苹果", 10.00);
Goods s1_goods2 = new Goods(R.drawable.xxx"香蕉", 15.00);
Goods s1_goods3 = new Goods(R.drawable.lll"荔枝", 25.00);
shops.add(new Shop(R.drawable.mi"华来水果店", s1_goods1, s1_goods2, s1_goods3));

Goods s2_goods1 = new Goods(R.drawable.bao"菠萝", 56.00);
Goods s2_goods2 = new Goods(R.drawable.yezi"椰子", 33.00);
Goods s2_goods3 = new Goods(R.drawable.mangguo"特大芒果", 26.00);
shops.add(new Shop(R.drawable.mangguo"海南特产水果", s2_goods1, s2_goods2, s2_goods3));
ShopListAdapter adapter = new ShopListAdapter(mContext, shops);
shop_list.setAdapter(adapter);
}
}

  1. 系统运行结果
安卓APP源码和设计报告——仿淘宝水果商城
安卓APP源码和设计报告——仿淘宝水果商城

图1图2
图1:首页页面,有几种商品的图片名称价格及商铺,还有用户评价及好评率,
还有搜索入口。
图2:分类页面,其中的品牌区,一些大牌商品,让用户挑选。

安卓APP源码和设计报告——仿淘宝水果商城
安卓APP源码和设计报告——仿淘宝水果商城

图3 图4
图3:分类页面的超市一栏,有一些日用百货,图书、零食、牛奶等
图4:分类页面的推荐分类一栏,推荐一些常用分类,充电宝、空调、口红、平板电脑、眼影、手机等

安卓APP源码和设计报告——仿淘宝水果商城
安卓APP源码和设计报告——仿淘宝水果商城

图5 图6
图5:发现页面,有一些水果店铺及一些商品的价格、名称等
图6:搜索的商品分类。

安卓APP源码和设计报告——仿淘宝水果商城
安卓APP源码和设计报告——仿淘宝水果商城

图7 图8
图7:注册页面
图8:登录页面

  1. 实验总结

对于本次仿淘宝商城系统的设计与实现,更加了解了移动应用开发程序的基本原理和方法,提高基于Android Studio对图形用户界面的设计和开发能力,以及对控件事件处理、数据存储以及网络访问的能力。通过本次实验,我成功的完成了实验内容。学会了使用Android中的一些控件去创建应用程序。我学会了基本布局的用法,自定义控件的方法,并了解了ListView及Fragment的详细用法,以及Android中单位的选择和使用,已经基本掌握了UI的相关知识。但是实验过程中还是遇到了一些问题的,我对布局的理解和应用还不是很清晰,而且感觉使用HTTP请求也很复杂很难,对它的使用的掌握仍需继续努力!

资源下载此资源下载价格为9.9云朵点击检测网盘有效后购买,VIP 5折、云炬VIP年会员免费
客服微信:2743319061
收藏 (4) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章资源,如无特殊说明或标注,均为本站网友和创作者贡献分享。如若本站内容侵犯了原著者的合法权益,可联系网站客服QQ2743319061删除。

云炬星球 安卓源码(带报告) 安卓APP源码和设计报告——仿淘宝水果商城 https://src.yunjunet.cn/875333.html

常见问题
  • 放心亲,我们不会为了几十块钱的东西坏了名声!
查看详情
  • 方法一:点击“立即下载.”按钮,付款后在下载弹窗的虚线框的隐藏信息里获取 方法二:在正文底部使用VIP查看隐藏的解压密码 方法三:联系【云炬网络】公众号客服获取
查看详情
  • 付款后会出现“立即下载”按钮(点击即可下载),如果下载失败也可以联系客服发订单截图补发。
查看详情
  • 登录购买会多端同步购买记录,永久可以查看反复下载;非登录购买仅将购买记录保存到本地浏览器中,浏览器cookie清除后无法再次下载。先右上角点登录,然后点击微信图标可以快速授权注册登录^_^
查看详情
  • 可以试看。点击”查看演示“或“试看预览”按钮可以试读从资料目录中节选的部分内容,也可以自己指定想试看的内容。
查看详情
  • 原因一:本站所有资源已开启有效性检测(服务器24h全自动监测),当监测到下载链接无法访问时会提示“该资源已失效,请勿购买”,遇到这种情况可以联系客服修复失效的下载链接,或直接联系客服在淘宝下单购买即可。(检测原理:购买前服务器程序会预访问下载链接,响应值为200说明资源有效允许购买,响应值为404或502等报错说明资源失效禁止购买)。原因二:上传者未启用“下载”选项。
查看详情
官方客服团队

为您解决烦忧 - 24小时在线 专业服务