延续大学时做课程设计的思路,首先就是登陆

当然,在登陆之前还是有其他界面的,比如第一次登陆时会有欢迎导航界面,,启动应用时会显示logo界面。下一篇再介绍。

logo界面结束之后会进入登陆界面,当然,前提是没有自动登陆的用户(有自动登陆的用户,是跳过登陆界面,直接进入主界面的)。

登陆界面由两个输入框,两个可选按钮,两个按钮组成。界面虽然简单,但是费了很大的劲处理,简单罗列如下:

在输入框的左边显示一个头像,右边是一个一键清空的小叉叉;

输入学号时会自动匹配已登录过的用户,如果登录时勾选了记住密码时,选择了用户后会自动填充密码;

当用户名或密码为空时点击登录按钮,为空的输入框会抖动,并会有红色字体提示为空;

勾选自动登陆后,下次打开应用就会直接以该用户的账户自动登陆,而不会显示登陆界面。

首先是,带有头像和叉叉的输入框

代码如下:

public class ClearEditText extends EditText implements  OnFocusChangeListener, TextWatcher { /*** 删除按钮的引用*/private Drawable mClearDrawable; /*** 控件是否有焦点*/private boolean hasFoucs;public ClearEditText(Context context) { this(context, null); } public ClearEditText(Context context, AttributeSet attrs) { //这里构造方法也很重要,不加这个很多属性不能再XML里面定义this(context, attrs, android.R.attr.editTextStyle); } public ClearEditText(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}private void init() { //获取EditText的DrawableRight,假如没有设置我们就使用默认的图片mClearDrawable = getCompoundDrawables()[2]; if (mClearDrawable == null) {
//          throw new NullPointerException("You can add drawableRight attribute in XML");mClearDrawable = getResources().getDrawable(R.drawable.delete_selector); } mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight()); //默认设置隐藏图标setClearIconVisible(false); //设置焦点改变的监听setOnFocusChangeListener(this); //设置输入框里面内容发生改变的监听addTextChangedListener(this); } /*** 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件* 当我们按下的位置 在  EditText的宽度 - 图标到控件右边的间距 - 图标的宽度  和* EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向就没有考虑*/@Override public boolean onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_UP) {if (getCompoundDrawables()[2] != null) {boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight())&& (event.getX() < ((getWidth() - getPaddingRight())));if (touchable) {this.setText("");}}}return super.onTouchEvent(event);}/*** 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏*/@Override public void onFocusChange(View v, boolean hasFocus) { this.hasFoucs = hasFocus;if (hasFocus) { setClearIconVisible(getText().length() > 0); } else { setClearIconVisible(false); } } /*** 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去* @param visible*/protected void setClearIconVisible(boolean visible) { Drawable right = visible ? mClearDrawable : null; setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], right, getCompoundDrawables()[3]); } /*** 当输入框里面内容发生变化的时候回调的方法*/@Override public void onTextChanged(CharSequence s, int start, int count, int after) { if(hasFoucs){setClearIconVisible(s.length() > 0);}} @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } /*** 设置晃动动画*/public void setShakeAnimation(){this.setAnimation(shakeAnimation(5));}/*** 晃动动画* @param counts 1秒钟晃动多少下* @return*/public static Animation shakeAnimation(int counts){Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);translateAnimation.setInterpolator(new CycleInterpolator(counts));translateAnimation.setDuration(1000);return translateAnimation;}}

在定义输入框时:

        <cn.edu.wit.withelper.util.ClearEditTextandroid:id="@+id/userid"android:layout_weight="1"android:layout_width="0dip"android:layout_height="wrap_content"android:background="@drawable/et_userid_border"android:drawableLeft="@drawable/users_selector"android:drawableRight="@drawable/delete_selector"android:hint="请输入您的学号"android:inputType="number"android:focusableInTouchMode="true"android:padding="3dp"android:singleLine="true"android:textSize="25sp" />

抖动的动画也在上面定义了,

下面就介绍下拉列表,

     ib_spinner = (ImageButton) findViewById(R.id.ib_spinner);//一个图片,覆盖到输入框的右端ib_spinner.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// 弹出下拉列表ListView listView = new ListView(getApplicationContext());listView.setCacheColorHint(0x00000000);// 滑动时 不变色listView.setVerticalScrollBarEnabled(false);listView.setBackgroundColor(getResources().getColor(R.color.white));//设置透明度listView.getBackground().setAlpha(230);listView.setAdapter(new MyAdapter());pop = new PopupWindow(listView, etUserId.getWidth()+ib_spinner.getWidth(),LayoutParams.WRAP_CONTENT, true);// pop隐藏pop.setBackgroundDrawable(new ColorDrawable(0x00000000));pop.setOutsideTouchable(true);pop.setFocusable(true);
//              pop.setAnimationStyle(R.style.PopupAnimation);pop.showAsDropDown(etUserId, 0, -8);pop.update();}});

接下来就是,记住密码与自动登陆了

             if (1 == isAuto) {    //自动登录则存入数据库,且写到配置文件SharedPreferencesUtil.saveLoginUser(LoginActivity.this, user);userInfoServices.insertUserInfo(user);}else if (1 == isRemember) {   //记住密码就写入数据库userInfoServices.insertUserInfo(user);}

登陆成功后,就根据用户的选择,对数据进行处理

然后就是,如何实现登陆

 public static UserInfo login(UserInfo loginUser) {String URL = "http://www.******.com/API/Android/Login";final Map<String, String> params = new HashMap<String, String>();params.put("userID", loginUser.getUserId());params.put("password", loginUser.getPassword());JSONObject jsonResult = InterfaceUtil.getJSONObject(URL, params);if (jsonResult == null) {Log.i(TAG, "result = null");return loginUser;} else {Log.i(TAG, "result = " + jsonResult.toString());return getUserByJson(jsonResult, loginUser);}}
 public static JSONObject getJSONObject(String url, // 请求的URLMap<String, String> params // 请求的参数序列) {long timestamp = new Date().getTime();//时间戳params.put("timestamp", "" + timestamp);//signparams.put("sign", MD5Util.getMD5String(SALT + timestamp));String result = postRequestToServer(url, params);if (null == result) {Log.i(TAG, "result = null");return null;}else {Log.i(TAG, "result = " + result);JSONTokener jsonTokener = new JSONTokener(result);JSONObject json = null;try {json = (JSONObject) jsonTokener.nextValue();} catch (JSONException e) {e.printStackTrace();} finally {return json;}}//end of else}

这里就涉及到对网络的访问,对json的解析,以及对数据的封装

 public static String postRequestToServer(String url, // 请求的URLMap<String, String> params // 请求的参数序列) {
Log.i(TAG, "访问网络");HttpEntityEnclosingRequestBase httpRequest = new HttpPost(url);List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(params.size());for (Map.Entry<String, String> entry : params.entrySet()) {// 构建表单字段内容nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));}String strResult = "";try {httpRequest.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8"));HttpClient client = new DefaultHttpClient();HttpParams httpparams = client.getParams();HttpConnectionParams.setConnectionTimeout(httpparams,7000);HttpConnectionParams.setSoTimeout(httpparams,7000);// 执行请求HttpResponse httpResponse = client.execute(httpRequest);// 判断返回结果,200则说明正确返回if (httpResponse.getStatusLine().getStatusCode() == 200) {// 从返回的结果中获取内容strResult = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");} else {strResult = null;}} catch (Exception e) {e.printStackTrace();Message msg = new Message();msg.what = Task.ERROR_NETEXCEPTION ;msg.obj = e;MainService.handler.sendMessage(msg);strResult = null;} finally {return strResult;}}

本应用中,所有的网络访问都是通过这个函数实现的

还有一个获取网络图片的函数,在本应用中没有使用,是准备用来获取用户头像的

 /*** 通过url获取图片* @param url* @return*/public static Drawable getNetImage(URL url) {if (null == url)return null;try {HttpURLConnection connection = (HttpURLConnection) url.openConnection();return Drawable.createFromStream(connection.getInputStream(),"image");} catch (IOException e) {e.printStackTrace();}return null;}

还有一个就是对SharedPreferences的操作;

 /*** 保存登录用户信息* @param context* @param user*/public static void saveLoginUser(Context context, UserInfo user) {SharedPreferences sp = context.getSharedPreferences(LOGIN_USER, Context.MODE_PRIVATE);Editor editor = sp.edit();editor.putString(UserInfo.USERID, user.getUserId());editor.putString(UserInfo.SESSIONID, user.getSessionId());editor.putString(UserInfo.USERNAME, user.getUserName());editor.commit();}/*** 获取登录用户信息* @param context* @return*/public static UserInfo getLoginUser(Context context) {SharedPreferences sp = context.getSharedPreferences(LOGIN_USER, Context.MODE_PRIVATE);String userId = sp.getString(UserInfo.USERID, "");String session = sp.getString(UserInfo.SESSIONID, "");String userName = sp.getString(UserInfo.USERNAME, "");if ("".equals(userId))return null;UserInfo user = new UserInfo();user.setUserId(userId);user.setSessionId(session);user.setUserName(userName);return user;}

登陆差不多就这么些东西,现在看来有很多东西都太low了,但还是原汁原味地展示出来。明天把项目的源码上传到github上,有时间就修改一下,希望有兴趣,或者有心赐教的大神多多指点。

ps:自动获取标签太烂了

本文出自 “年少的风” 博客,谢绝转载!

校园助手APP--登陆相关推荐

  1. java计算机毕业设计基于安卓Android的校园助手APP

    项目介绍  网络的广泛应用给生活带来了十分的便利.所以把校园助手与现在网络相结合,利用java技术建设校园助手APP,实现校园助手的信息化.则对于进一步提高校园助手发展,丰富校园助手经验能起到不少的促 ...

  2. node.js毕业设计安卓校园代办助手app(程序+APP+LW)

    该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程.欢迎交流 项目运行 环境配置: Node.js+ Vscode +Mysql5.7 + HBuilderX+Navicat11+Vue+ ...

  3. android校园淘论文,基于安卓的校园寻物app的设计与实现--大学生毕业论文(设计).doc...

    基于安卓的校园寻物app的设计与实现--大学生毕业论文(设计) 文 献 信 息 检 索 论 文 课题名称:基于安卓的校园管理软件的设计与实现 负 责 人: 班 级: 学 号: 完成时间: 2014年1 ...

  4. 校园助手APP--简介及框架

    最近没有怎么编码,就把断断续续做了半年的毕业设计拿出来回顾一下. 校园助手,分为服务器端与Android客户端,在此主要介绍客户端,服务器是一位大神用node.js写的. 主要实现的功能有:登陆,信息 ...

  5. 魔兽世界 助手 无法连接服务器,魔兽世界随身助手app打不开 魔兽世界军团再临助手无法登录解决办法...

    魔兽世界随身助手app打不开怎么回事?魔兽世界军团再临助手登录不上怎么办?当你下载安装魔兽世界app后,发现网络连接不上或无法打开的状况,可以来看看本文提供的解决办法哦! 魔兽世界随身助手app打不开 ...

  6. 基于安卓平台的校园社交app设计

    目 录 1 绪论 3 1.1 研究背景和意义 3 1.2 研究现状 3 1.3 研究内容 4 1.4 论文结构 4 2 系统设计 5 2.1 总体功能模块设计 5 2.2 服务端模块 5 2.3 安卓 ...

  7. 基于人工智能的智慧校园助手(springboot+springcloud+redis+vue+vant ui+element ui+mysql+Elasticsearch+RabbitMQ项目)

    部分功能演示地址 由于录视频时还没开发完,只有部分功能展示. 第一章 需求分析 学校是促进社会发展和个体发展的主要载体,随着信息化趋势的不断加强,信息技术越来越深度地融入高校的教育.教学及校园生活之中 ...

  8. 订阅号助手App发布 手机也能管理公众号了

    盼着许久的微信订阅号助手app终于发布了!" 微信团队发布「订阅号助手」App,支持公众号运营者在手机上发表内容.查看和回复消息.管理已关注用户和帐号.暂时只支持iOS平台,Android平 ...

  9. 原神光环助手下的算什么服务器,原神光环助手app

    <原神光环助手app>是一款能随时了解到很多的游戏的新鲜资讯内容和各种游戏的新玩法的手机软件,各种游戏的攻略随时线上带到你的面前哦!让你知道各种游戏的新玩法!感兴趣的用户快和小编一起下载体 ...

  10. Android逆向分析案例——某点评APP登陆请求数据解密

    今天,七夕,单身23载的程序汪,默默地写着博客~ 上一次的逆向分析案例中讲了如何去分析某酒店的APP登陆请求,为了进一步学习如何逆向分析以及学习其他公司的网络传输加解密,本次案例将继续就登陆请求的数据 ...

最新文章

  1. linux下 /etc/profile、~/.bash_profile ~/.profile的执行过程
  2. AI公开课:19.03.06何晓冬博士《自然语言与多模态交互前沿技术》课堂笔记以及个人感悟
  3. spss主成分综合得分_【SPSS因子分析】在SPSS中对医学多个数值变量进行因子分析 —【杏花开医学统计】...
  4. ionic入门教程第一课--环境搭建和新建ionic项目
  5. atom对比 vscode_VS Code、ATOM这些开源文本编辑器的代码实现中有哪些奇技淫巧?...
  6. Chapter 04-Using Conversion Functions and Conditional Expressions-Conditional Expressions
  7. java设计模式--创建模式--单例模式
  8. 学习Java的9张思维导图
  9. AI虚拟偶像正崛起,是否可以取代你的idol?
  10. java怎么查看jdk版本_java版本和jdk版本必须一样
  11. python os.system()和os.popen()
  12. python学习--DataFrame
  13. mysql5.6安装sys库_编译安装MySQL5.6.23
  14. PID原理的详细分析及调节过程
  15. git与gitee的基础使用方法
  16. 绩效管理的目的和目标
  17. arcgis中如何导出奥维可识别的图_如何将地图及奥维对象导出成图片 | 奥维互动地图浏览器...
  18. 3DMAX高级光照相关的名词解释
  19. 鸟哥私房菜服务器架设篇(二):基础网络概念
  20. 中软国际python机试题_【中软国际c语言开发笔试试题及答案】 - 面试网

热门文章

  1. python中交集并集用什么符号表示_Python实现两个list求交集,并集,差集的方法示例...
  2. 《程序员修炼之道》读书笔记
  3. linux使用tmux后台运行程序
  4. Linux下让程序后台运行
  5. ESP8266_设置AP模式,WiFi名称密码
  6. 【VBA】Excel拆分表格,并且复制格式
  7. 使用Epub.js打开本地Epub文件
  8. 夏日悦动“正当红”魅焰红版荣耀畅玩手环A2惊艳开售
  9. 2021高考成绩查询怎么查小分,2021微信哪个小程序可以查成绩 高考成绩怎么查
  10. TStack运维笔记(04)- 配置VPC网络及告警设置