android第四次作业
一、团队成员
姓名 | 学号 | 班级 | 博客 |
沈顺文 | 1600802058 | 162 | 博客地址 |
二、团队项目APK
https://pan.baidu.com/s/1odhg5CsD92qNOnnoer4sEA
三、团队项目代码
https://git.coding.net/insist_shen/android_coding_kill.git
四、团队项目介绍
项目展示
https://pan.baidu.com/s/1QMmYz0djqHwBsJC-bVe-SQ
4.1 团队项目的总体效果截图
1.项目启动页面
2.项目登录界面
3.项目注册界面
4.项目主界面
5.代码闯关界面
6.代码搜索界面
7.代码学习界面
8.代码交流界面
9.个人设置界面
10.添加好友界面
4.2 实现的功能及其效果的描述
1.登录注册界面实现与数据库的连接可以注册多个账号进行登录,并且会根据注册信息进行个人界面的名称设置等
2.对相应的登录注册账号进行了查重,不允许相同账号以及用户名的注册,且登录注册等信息不可以出现空格和换行符等特殊符号
3.登录界面若连续输错三次密码,则会弹出验证码进行验证,防止恶意破解密码
4.可以进行个人设置中签名的更改
5.个人设置中可以从相册中获取头像,并且同步设置背景墙
6.代码交流中,可以进行滑动切换查看最新,最热的贴文
五、关键代码
输入框中禁止输入空格和换行符
1 //用户名 2 final EditText first = (EditText) findViewById(R.id.account); 3 first.addTextChangedListener(new TextWatcher() { 4 /*不允许输入空格和换行符*/ 5 @Override 6 public void onTextChanged(CharSequence s, int start, int before, 7 int count) { 8 9 if (s.toString().contains("\n")) { 10 String[] str ; 11 str = s.toString().split("\n"); 12 String str1 = ""; 13 for (int i = 0; i < str.length; i++) { 14 str1 += str[i]; 15 } 16 first.setText(str1); 17 18 first.setSelection(start); 19 20 } 21 if (s.toString().contains(" ")) { 22 String[] str ; 23 str = s.toString().split(" "); 24 String str1 = ""; 25 for (int i = 0; i < str.length; i++) { 26 str1 += str[i]; 27 } 28 first.setText(str1); 29 30 first.setSelection(start); 31 32 } 33 34 } 35 36 @Override 37 public void beforeTextChanged(CharSequence s, int start, int count, 38 int after) { 39 40 } 41 42 @Override 43 public void afterTextChanged(Editable s) { 44 } 45 });
将信息插入数据库中
1 dbhelper=new Mydatabase(this,"ssw.db",null,1); 2 dbhelper.getWritableDatabase(); 3 final SQLiteDatabase mydb=dbhelper.getWritableDatabase(); 4 final Button apply = (Button) findViewById(R.id.apply); 5 apply.setOnClickListener(new View.OnClickListener() { 6 @Override 7 public void onClick(View v) { 8 int flag=0;//判断是否判断验证码为空 只要账户不存在才需要判断验证码的正确与错误 9 String username=((EditText)findViewById(R.id.userid)).getText().toString(); 10 String useraccount=((EditText)findViewById(R.id.account)).getText().toString(); 11 String userpassword=((EditText)findViewById(R.id.pwd)).getText().toString(); 12 String reuserpassword=((EditText)findViewById(R.id.repwd)).getText().toString(); 13 if(!"".equals(username)&&!"".equals(useraccount)&&!"".equals(userpassword)&&!"".equals(reuserpassword)) { 14 if(!reuserpassword.equals(userpassword)) 15 { 16 Toast.makeText(apply.this,"两次输入的密码不一致,请重新输入",Toast.LENGTH_LONG).show(); 17 ((EditText)findViewById(R.id.repwd)).setText(""); 18 ((EditText)findViewById(R.id.pwd)).setText(""); 19 ((EditText)findViewById(R.id.repwd)).requestFocus(); 20 } 21 else{ 22 Cursor cursor=mydb.query("information",null,null,null,null,null,null,null); 23 if(cursor.moveToFirst()) 24 { 25 26 do{ 27 if(username.equals(cursor.getString(0))) 28 { 29 30 Toast.makeText(apply.this, "该用户名已存在!请重新输入", Toast.LENGTH_SHORT).show(); 31 ((EditText)findViewById(R.id.userid)).setText(""); 32 ((EditText)findViewById(R.id.userid)).requestFocus(); 33 flag++; 34 break; 35 } 36 else if(useraccount.equals(cursor.getString(1))) 37 { 38 39 Toast.makeText(apply.this, "该账号已存在!请重新输入", Toast.LENGTH_SHORT).show(); 40 ((EditText)findViewById(R.id.account)).setText(""); 41 ((EditText)findViewById(R.id.account)).requestFocus(); 42 flag++; 43 break; 44 } 45 } 46 while(cursor.moveToNext()); 47 48 49 50 /* while(!cursor.isAfterLast()) 51 { 52 if(username.equals(cursor.getString(0))) 53 { 54 55 Toast.makeText(MainActivity.this, "该用户名已存在!请重新输入", Toast.LENGTH_SHORT).show(); 56 ((EditText)findViewById(R.id.username)).setText(""); 57 ((EditText)findViewById(R.id.username)).requestFocus(); 58 } 59 else if(useraccount.equals(cursor.getString(1))) 60 { 61 62 Toast.makeText(MainActivity.this, "该账号已存在!请重新输入", Toast.LENGTH_SHORT).show(); 63 ((EditText)findViewById(R.id.useraccount)).setText(""); 64 ((EditText)findViewById(R.id.useraccount)).requestFocus(); 65 } 66 else 67 { 68 cursor.moveToNext(); 69 } 70 71 }*/ 72 73 } 74 if(flag==0) 75 { 76 codeStr = et.getText().toString().trim(); 77 if (null == codeStr || TextUtils.isEmpty(codeStr)) 78 { 79 Toast.makeText(apply.this, "请输入验证码", Toast.LENGTH_LONG).show(); 80 return; 81 } 82 String code = codeUtils.getCode(); 83 //Log.e("code", code); 84 85 /*验证码的判断*/ 86 if (code.equalsIgnoreCase(codeStr)) { 87 cursor.close(); 88 ContentValues values = new ContentValues(); 89 values.put("username", username); 90 values.put("userid", useraccount); 91 values.put("password", userpassword); 92 mydb.insert("information", null, values); 93 Toast.makeText(apply.this, "注册成功", Toast.LENGTH_SHORT).show(); 94 Intent gotologin=new Intent(apply.this,codingkill.class); 95 startActivity(gotologin); 96 97 } 98 else 99 { 100 101 Toast.makeText(apply.this, "验证码错误", Toast.LENGTH_LONG).show(); 102 ((EditText)findViewById(R.id.et)).setText(""); 103 ((EditText)findViewById(R.id.et)).requestFocus(); 104 105 }
登录界面验证账号
1 dbhelper=new Mydatabase(this,"ssw.db",null,1); 2 final SQLiteDatabase mydb=dbhelper.getWritableDatabase(); 3 Button login=(Button)findViewById(R.id.login1); 4 final LinearLayout yanzhengma=(LinearLayout)findViewById(R.id.yanzhengma) ; 5 final EditText et = (EditText) findViewById(R.id.et); 6 login.setOnClickListener(new View.OnClickListener() 7 { 8 @Override 9 public void onClick(View v) { 10 String account=((EditText)findViewById(R.id.account1)).getText().toString(); 11 String passwd=((EditText)findViewById(R.id.pwd1)).getText().toString(); 12 //弹出验证码 13 if(myflag>2) 14 { 15 final EditText et = (EditText) findViewById(R.id.et); 16 et.addTextChangedListener(new TextWatcher() { 17 /*不允许输入空格和换行符*/ 18 @Override 19 public void onTextChanged(CharSequence s, int start, int before, 20 int count) { 21 22 if (s.toString().contains("\n")) { 23 String[] str ; 24 str = s.toString().split("\n"); 25 String str1 = ""; 26 for (int i = 0; i < str.length; i++) { 27 str1 += str[i]; 28 } 29 et.setText(str1); 30 31 et.setSelection(start); 32 33 } 34 if (s.toString().contains(" ")) { 35 String[] str ; 36 str = s.toString().split(" "); 37 String str1 = ""; 38 for (int i = 0; i < str.length; i++) { 39 str1 += str[i]; 40 } 41 et.setText(str1); 42 43 et.setSelection(start); 44 45 } 46 47 } 48 49 @Override 50 public void beforeTextChanged(CharSequence s, int start, int count, 51 int after) { 52 53 } 54 55 @Override 56 public void afterTextChanged(Editable s) { 57 } 58 }); 59 60 61 yanzhengma.setVisibility(yanzhengma.VISIBLE); 62 image =(ImageView)findViewById(R.id.image); 63 64 image.setOnClickListener(new View.OnClickListener(){ 65 @Override 66 public void onClick(View v) { 67 codeUtils = CodeUtils.getInstance(); 68 Bitmap bitmap = codeUtils.createBitmap(); 69 image.setImageBitmap(bitmap); 70 } 71 }); 72 73 codeStr = et.getText().toString().trim(); 74 if (null == codeStr || TextUtils.isEmpty(codeStr)) 75 { 76 Toast.makeText(codingkill.this, "请输入验证码", Toast.LENGTH_LONG).show(); 77 return; 78 } 79 String code = codeUtils.getCode(); 80 //Log.e("code", code); 81 82 /*验证码的判断*/ 83 if (code.equalsIgnoreCase(codeStr)) { 84 //Toast.makeText(codingkill.this, "验证码正确", Toast.LENGTH_LONG).show(); 85 86 } 87 else 88 { 89 90 Toast.makeText(codingkill.this, "验证码错误", Toast.LENGTH_LONG).show(); 91 ((EditText)findViewById(R.id.et)).setText(""); 92 ((EditText)findViewById(R.id.et)).requestFocus(); 93 return; 94 } 95 96 } 97 98 /* ------------未显示验证码---------------*/ 99 if(!"".equals(account)&&!"".equals(passwd)) 100 { 101 int count=0; 102 Cursor cursor=mydb.query("information",null,null,null,null,null,null,null); 103 if(cursor.moveToFirst()) { 104 do { 105 if(account.equals(cursor.getString(1))&&!passwd.equals(cursor.getString(2))) 106 { 107 Toast.makeText(codingkill.this,"密码错误,请重新输入!",Toast.LENGTH_LONG).show(); 108 ((EditText)findViewById(R.id.pwd1)).setText(""); 109 ((EditText)findViewById(R.id.pwd1)).requestFocus(); 110 count++; 111 myflag++; 112 break; 113 } 114 if(account.equals(cursor.getString(1))&&passwd.equals(cursor.getString(2))) 115 { 116 //存储当前用户名 117 //Intent intent=new Intent(); 118 String usename=cursor.getString(0); 119 String userid=cursor.getString(1); 120 //String sign=cursor.getString(3); 121 SharedPreferences sp=getSharedPreferences("insist",MODE_PRIVATE); 122 SharedPreferences.Editor editor =sp.edit(); 123 editor.putString("userid",userid); 124 editor.putString("usename",usename); 125 //editor.putString("sign",sign); 126 editor.commit(); 127 128 //存储当前用户名 129 130 131 // Log.i("the name is","cursor.getString(0)"); 132 Toast.makeText(codingkill.this,"登陆成功,正在跳转!",Toast.LENGTH_LONG).show(); 133 Intent intent1=new Intent(codingkill.this,home.class); 134 135 136 //跳转到个人设置界面 137 startActivity(intent1); 138 139 140 //跳转到主页面 141 //startActivity(intent1); 142 count++; 143 break; 144 } 145 if(account.equals(cursor.getString(1))) 146 { 147 count++; 148 } 149 } 150 while (cursor.moveToNext()); 151 } 152 if(count==0) 153 { 154 Toast.makeText(codingkill.this,"账号不存在,请先注册一个账号",Toast.LENGTH_LONG).show(); 155 } 156 } 157 else 158 { 159 Toast.makeText(codingkill.this,"账号或密码不能为空",Toast.LENGTH_LONG).show(); 160 } 161 } 162 }); 163 final TextView apply=(TextView) findViewById(R.id.apply1); 164 apply.setOnClickListener(new View.OnClickListener() 165 { 166 @Override 167 public void onClick(View v) 168 { 169 Intent intent2=new Intent(codingkill.this,apply.class); 170 startActivity(intent2); 171 } 172 }); 173 } 174 }
个人设置界面获取相册中头像,以及相应背景墙的变换
1 Glide.with(this).load(R.drawable.touxiang) 2 .bitmapTransform(new BlurTransformation(this, 25), new CenterCrop(this)) 3 .into(back); 4 /* 设置圆形图像 */ 5 Glide.with(this).load(R.drawable.touxiang) 6 .bitmapTransform(new CropCircleTransformation(this)) 7 .into(head); 8 9 10 } 11 12 public static final Bitmap getBitmap(ContentResolver cr, Uri url) 13 throws FileNotFoundException, IOException { 14 InputStream input = cr.openInputStream(url); 15 Bitmap bitmap = BitmapFactory.decodeStream(input); 16 input.close(); 17 return bitmap; 18 } 19 protected void onActivityResult(int requestCode,int resultCode,Intent data){ 20 if (requestCode == 1) { 21 // 从相册返回的数据 22 if (data != null) { 23 // 得到图片的全路径 24 Uri uri = data.getData(); 25 //getBitmap(,uri); 26 //Uri uri =new URL(getIntent().getExtras().getString("123")); 27 // Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),uri); 28 // head.setImageURI(uri); 29 Glide.with(this).load(uri) 30 .bitmapTransform(new CropCircleTransformation(this)) 31 .into(head); 32 Glide.with(this).load(uri) 33 .bitmapTransform(new BlurTransformation(this, 25), new CenterCrop(this)) 34 .into(back); 35 } 36 } 37 }
代码交流中,页面切换和相应标题的对应
1 private void initViews() { 2 title = (TextView) findViewById(R.id.title); 3 item_zuixin = (TextView) findViewById(R.id.zuixin); 4 item_zuire = (TextView) findViewById(R.id.zuire); 5 6 item_zuixin.setOnClickListener(this); 7 item_zuire.setOnClickListener(this); 8 9 10 vp = (ViewPager) findViewById(R.id.mainViewPager); 11 oneFragment = new OneFragment(); 12 twoFragment = new TwoFragment(); 13 14 //给FragmentList添加数据 15 mFragmentList.add(oneFragment); 16 mFragmentList.add(twoFragment); 17 18 } 19 20 /** 21 * 点击底部Text 动态修改ViewPager的内容 22 */ 23 @Override 24 public void onClick(View v) { 25 switch (v.getId()) { 26 case R.id.zuixin: 27 vp.setCurrentItem(0, true); 28 break; 29 case R.id.zuire: 30 vp.setCurrentItem(1, true); 31 break; 32 } 33 } 34 35 36 public class FragmentAdapter extends FragmentPagerAdapter { 37 38 List<Fragment> fragmentList = new ArrayList<Fragment>(); 39 40 public FragmentAdapter(FragmentManager fm, List<Fragment> fragmentList) { 41 super(fm); 42 this.fragmentList = fragmentList; 43 } 44 45 @Override 46 public Fragment getItem(int position) { 47 return fragmentList.get(position); 48 } 49 50 @Override 51 public int getCount() { 52 return fragmentList.size(); 53 } 54 55 } 56 57 /* 58 *由ViewPager的滑动修改底部导航Text的颜色 59 */ 60 private void changeTextColor(int position) { 61 if (position == 0) 62 { 63 item_zuixin.setTextColor(Color.parseColor("#66CDAA")); 64 item_zuire.setTextColor(Color.parseColor("#ffffff")); 65 } 66 else if (position == 1) 67 { 68 item_zuixin.setTextColor(Color.parseColor("#ffffff")); 69 item_zuire.setTextColor(Color.parseColor("#66CDAA")); 70 } 71 } 72 }
六、运行其他团队项目的apk
1.盖星辰、杨虎秀、张雄组------神经质大逃亡
总结:是一款有趣的游戏app,界面大方简洁,具有一定的可玩性
优点:可以进行人物的切换以及难度的切换,具备操控人物等手势功能,项目较为成熟
缺点:游戏中,小人的下落时间过快,且操作性上存在一定的问题,不能很顺滑流畅的操作小人的移动
如果我加入这个项目,会对移动人物进行一定的改进,使得操作更加顺滑简便,并且会增加自定义人物用户名等信息的注册,避免只有两个人物排名信息的问题
2.洪居兴、邓旺、李洪岩组------游山玩水app
总结:这款app界面简洁,采取短信动态登陆的方式较为新颖
优点:UI界面设计的好,给人眼前一新的感觉,并且有其特色的动态获取信息登录功能,且目前实现的功能较多
缺点:由于apk没有通过认证,每日的注册数目有限,导致有时候不可以及时注册成功,对注册有一定的影响,且注册界面有时候会出现闪退的情况,还有少部分搜索功能等还未完善。
如果我加入这个项目,会对其功能进行一定的完善,因为我自身的项目是由自己一个人完成的,完成度还没有他们这些项目高,且一个人完成费事费力,效率较低,如果我加入这个项目,会对其搜索功能进行一定程度的完善
3.李怡龙、刘显云、刘志祥组-------windroid App
总结:与pc端有很好的结合,使用了服务器连接等技术
优点:功能十分新颖,技术含量比较高,主要针对计算机网络方面的知识并且与android的开发相结合,使得可以通过pc端和移动端同时进行操作
缺点:目前功能还较少,专业性过强,实用性比较弱,有些功能实现的时候会出现闪退的情况。
如果我加入这个项目,会让其操作更加简洁,使得用户更加容易接受,增强其实用性
4.杨圣豪、汤文涛、黄东强组-------校园二手交易App
总结:是一个基于校园的二手交易平台,功能一目了然,且界面比较简洁
优点:大致的功能及界面都已经做出,且与数据库相连接具有一定的交互性,相比起相同组下的交易软件,完成度比较高
缺点:有时候会出现闪退的情况,且图片上传不能及时的获取,还存在留言上的一些小bug等等
如果我参加这个项目,会对现有的UI界面进行一定的优化,解决图片上传等方面的功能等等
5.李钊组--------大话乒乓
总结:是一个针对乒乓球爱好者的了解乒乓事物的综合app
优点:是由一个人独立完成的,基本的功能都已经实现,且具有一定的实用性,可以查询到相关的比赛视频,以及实时的世界排名等
缺点:目前来看拥有的功能还比较少,视频是通过自身直接上传的,在使用app时,有些视频存在打不开的现象,且有闪退的问题
如果我参加这个项目,会对上述问题进行一定的完善,并增加一些功能,留言互动等交流板块等等,让乒乓爱好者可以在上面互相交流,并增加一些教学性的视频等等
七、项目遇到的问题
沈顺文 1600802058 遇到的问题:
1.在实现个人设置界面时候用到的viewpage和fragment的时候,发现在fragment中是不可以直接通过findViewByid获取相应属性进行监听的,因为fragment继承的是独立的android.support.v4.app.Fragment,fragment不属于一个activity,
后来通过上网查资料,发现可以在其onCreateView方法中,通过返回一个view的值(view的属性为activity)来进行监听,具体做法如下
1 @Override 2 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 3 // Inflate the layout for this fragment 4 //return inflater.inflate(R.layout.activity_two_fragment, container, false); 5 View view=inflater.inflate(R.layout.activity_two_fragment,container,false); 6 LinearLayout enter=(LinearLayout)view.findViewById(R.id.hot2); 7 LinearLayout enter1=(LinearLayout)view.findViewById(R.id.hot3) ; 8 LinearLayout enter3=(LinearLayout)view.findViewById(R.id.hot1); 9 enter.setOnClickListener(new View.OnClickListener() { 10 @Override 11 public void onClick(View v) { 12 Intent enter=new Intent(getActivity(),Context.class); 13 startActivity(enter); 14 } 15 }); 16 enter1.setOnClickListener(new View.OnClickListener() { 17 @Override 18 public void onClick(View v) { 19 Intent enter1=new Intent(getActivity(),Context2.class); 20 startActivity(enter1); 21 } 22 }); 23 enter3.setOnClickListener(new View.OnClickListener() { 24 @Override 25 public void onClick(View v) { 26 Intent enter3=new Intent(getActivity(),hot.class); 27 startActivity(enter3); 28 } 29 }); 30 return view; 31 }
2.个人设置中信息的获取问题,一开始用的是intent和bundle在登录界面获取相应的账号,然后再个人设置界面中进行取值,但是中间跨越了一个首页,导致造成闪退的后果,在老师的帮助下,改用SharePreference进行数据的存储,避免了intent必须在启动相应传输页面才能传值得这一问题,使得可以跨越界面进行 账号和用户名的匹配,具体SharePreference用法如下
登录界面的存入id
1 //存储当前用户名 2 //Intent intent=new Intent(); 3 String usename=cursor.getString(0); 4 String userid=cursor.getString(1); 5 //String sign=cursor.getString(3); 6 SharedPreferences sp=getSharedPreferences("insist",MODE_PRIVATE); 7 SharedPreferences.Editor editor =sp.edit(); 8 editor.putString("userid",userid); 9 editor.putString("usename",usename);
个人设置中,通过key值取出相应的用户名
1 SharedPreferences sp=getSharedPreferences("insist",MODE_PRIVATE); 2 String username=sp.getString("usename","youke"); 3 name.setText(username);
3.在安装apk之后,进行安装到真机的时候总是提醒waiting for debugger 的错误,通过上网查了资料,尝试很多方法都没有用。
最后在手机的开发者选项中找到了,选择调试应用这一个板块,并且将等待调试器关闭则可正常运行
八、项目分工
姓名 | 分工 | 工作比例 | 分数(10分) |
沈顺文 | UI、数据库、功能实现 | 100% | 10 |