功能强大的登录界面Android实现代码

功能强大的登录界面Android实现代码,第1张

概述前言    一个好的应用需要一个有良好的用户体验的登录界面,现如今,许多应用的的登录界面都有着用户名,密码一键删除,用户名,密码为空提示,以及需要输入验证码的功能。看着csdn上的大牛们

前言

     一个好的应用需要一个有良好的用户体验的登录界面,现如今,许多应用的的登录界面都有着用户名,密码一键删除,用户名,密码为空提示,以及需要输入验证码的功能。看着csdn上的大牛们的文章,心里想着也写一个登录界面学习学习,许多东西都是参考别的文章,综合起来的。废话少说,接下来看看是如何实现的。 

ps:由于懒得抠图。所以程序的图标很难看。
程序运行时的图示:

首先是布局文件没有什么难度。

<relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  xmlns:tools="http://schemas.androID.com/tools" androID:layout_wIDth="match_parent"  androID:layout_height="match_parent" androID:paddingleft="@dimen/activity_horizontal_margin"  androID:paddingRight="@dimen/activity_horizontal_margin"  androID:paddingtop="@dimen/activity_vertical_margin"  androID:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">   <ImageVIEw  androID:ID="@+ID/tv_login"  androID:src="@drawable/ic_launcher"  androID:layout_wIDth="match_parent"  androID:layout_height="wrap_content"  androID:layout_alignParenttop="true"  androID:gravity="center"  />  <com.example.administrator.texttest.DeletableEditText  androID:ID="@+ID/tv_user"  androID:layout_wIDth="match_parent"  androID:layout_height="wrap_content"  androID:textSize="30dp"  androID:layout_below="@ID/tv_login"  androID:drawableleft="@drawable/ic_launcher"  androID:drawableRight="@drawable/ic_launcher"  androID:hint="请输入账户"  androID:ems="10"/>  <com.example.administrator.texttest.DeletableEditText  androID:ID="@+ID/tv_psd"  androID:layout_wIDth="match_parent"  androID:layout_height="wrap_content"  androID:textSize="30dp"  androID:layout_below="@ID/tv_user"  androID:drawableleft="@drawable/ic_launcher"  androID:drawableRight="@drawable/ic_launcher"  androID:hint="请输入密码"  androID:inputType="textPassword"  androID:ems="10"/>  <linearLayout  androID:ID="@+ID/lyYanzhengma"  androID:orIEntation="horizontal"  androID:layout_wIDth="match_parent"  androID:layout_height="wrap_content"   androID:layout_below="@ID/tv_psd">  <linearLayout   androID:ID="@+ID/lyVerify"   androID:orIEntation="horizontal"   androID:layout_wIDth="wrap_content"   androID:layout_height="wrap_content">   <TextVIEw   androID:ID="@+ID/tvHIDeA"   androID:layout_wIDth="70dp"   androID:layout_height="70dp"   androID:visibility="gone"   androID:gravity="center"   androID:textSize="30dp"   />   <TextVIEw   androID:ID="@+ID/tvHIDeB"   androID:layout_wIDth="70dp"   androID:layout_height="70dp"   androID:visibility="gone"   androID:gravity="center"   androID:textSize="30dp"   />   <TextVIEw   androID:ID="@+ID/tvHIDeC"   androID:layout_wIDth="70dp"   androID:layout_height="70dp"   androID:visibility="gone"   androID:gravity="center"   androID:textSize="30dp"   />   <TextVIEw   androID:ID="@+ID/tvHIDeD"   androID:layout_wIDth="70dp"   androID:layout_height="70dp"   androID:visibility="gone"   androID:gravity="center"   androID:textSize="30dp"   />  </linearLayout>  <linearLayout   androID:ID="@+ID/IV_num"   androID:orIEntation="horizontal"   androID:layout_wIDth="wrap_content"   androID:layout_height="wrap_content">   <ImageVIEw   androID:layout_height="70dp"   androID:layout_wIDth="50dp"   androID:ID="@+ID/ivNumA"/>   <ImageVIEw   androID:layout_height="70dp"   androID:layout_wIDth="50dp"   androID:ID="@+ID/ivNumB"/>   <ImageVIEw   androID:layout_height="70dp"   androID:layout_wIDth="50dp"   androID:ID="@+ID/ivNumC"/>   <ImageVIEw   androID:layout_height="70dp"   androID:layout_wIDth="50dp"   androID:ID="@+ID/ivNumD"/>  </linearLayout>   <linearLayout   androID:orIEntation="horizontal"   androID:layout_height="wrap_content"   androID:layout_wIDth="match_parent">   <EditText   androID:layout_height="wrap_content"   androID:layout_wIDth="120dp"   androID:textSize="30dp"   androID:ID="@+ID/etCheck"   androID:maxLength="4"   androID:singleline="true"   androID:hint="验证码"/>   <TextVIEw   androID:layout_height="wrap_content"   androID:layout_wIDth="wrap_content"   androID:text="结果"   androID:ID="@+ID/tvCheck"   androID:textSize="30dp"   androID:visibility="gone"/>  </linearLayout>     </linearLayout>  <button  androID:ID="@+ID/bt_login"  androID:text="登 录"  androID:textSize="30dp"  androID:layout_below="@ID/lyYanzhengma"  androID:layout_wIDth="match_parent"  androID:layout_height="wrap_content" />  </relativeLayout> 

然后是加载一些布局文件,和一些控件的初始化

//登录按钮  private button btLogin;  //账户  private DeletableEditText userEditText;  //密码  private DeletableEditText psdEditText;    //验证码的数字文本  private TextVIEw tvHIDeA,tvHIDeB,tvHIDeC,tvHIDeD;   //验证码的图片文本  private ImageVIEw ivNumA,ivNumB,ivNumC,ivNumD;  //验证码输入文本  private EditText etCheck;  //验证码的检测显示文本  private TextVIEw tvCheck;   //存储每个验证码的数字  private String numStrTmp = "";  //存储整个验证码的数字  private String numStr = "";   //存储验证码的数组  private int[] numArray = new int[4];  //存储颜色的数组  private int[] colorArray = new int[6];   @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentVIEw(R.layout.activity_main);  setupVIEws();   }   private voID setupVIEws() {  btLogin = (button) findVIEwByID(R.ID.bt_login);  btLogin.setonClickListener(new OnClickListenerImpl());  userEditText = (DeletableEditText) findVIEwByID(R.ID.tv_user);  psdEditText = (DeletableEditText) findVIEwByID(R.ID.tv_psd);    tvHIDeA = (TextVIEw) findVIEwByID(R.ID.tvHIDeA);  tvHIDeB = (TextVIEw) findVIEwByID(R.ID.tvHIDeB);  tvHIDeC = (TextVIEw) findVIEwByID(R.ID.tvHIDeC);  tvHIDeD = (TextVIEw) findVIEwByID(R.ID.tvHIDeD);   ivNumA = (ImageVIEw) findVIEwByID(R.ID.ivNumA);  ivNumB = (ImageVIEw) findVIEwByID(R.ID.ivNumB);  ivNumC = (ImageVIEw) findVIEwByID(R.ID.ivNumC);  ivNumD = (ImageVIEw) findVIEwByID(R.ID.ivNumD);   ivNumA.setonClickListener(new OnClickListenerImpl());  ivNumB.setonClickListener(new OnClickListenerImpl());  ivNumC.setonClickListener(new OnClickListenerImpl());  ivNumD.setonClickListener(new OnClickListenerImpl());   tvCheck = (TextVIEw) findVIEwByID(R.ID.tvCheck);  etCheck = (EditText) findVIEwByID(R.ID.etCheck);   setNum(); 

自定义EditText的实现过程:

思路:设置两个EIDtText,在这个EditText中各设置图标。左边图标为账户和密码的图标提示,右边图标为一键删除 。因为EditText中的图标没有onClick事件,为了实现点击一键删除效果所以要使用OntouchEvent回调方法,监听点击事件来判断实现一键删除。当账户和密码没有字符时,右边的一键删除图标设置隐藏,当有字符时,设置图标显示。当点击到右边图标范围时,删除所在行的字符。从而实现一键删除。 此外,当账户和密码为空而要登录时。这两行抖动提示。
废话不多说,直接上代码注释很清楚。

package com.example.administrator.texttest;  import androID.content.Context; import androID.graphics.drawable.Drawable; import androID.text.Editable; import androID.text.TextWatcher; import androID.util.AttributeSet; import androID.vIEw.MotionEvent; import androID.vIEw.VIEw; import androID.vIEw.animation.Animation; import androID.vIEw.animation.CycleInterpolator; import androID.vIEw.animation.TranslateAnimation; import androID.Widget.EditText;  /**  * Created by administrator on 2015-10-10.  */ public class DeletableEditText extends EditText {   private Drawable mRightDrawable;  private boolean isHasFocus;     public DeletableEditText(Context context) {  this(context,null);  }   public DeletableEditText(Context context,AttributeSet attrs) {  this(context,attrs,androID.R.attr.editTextStyle);  }   public DeletableEditText(Context context,AttributeSet attrs,int defStyleAttr) {  super(context,defStyleAttr);  setupVIEws();  }   private voID setupVIEws() {   //取的vIEw的上下左右边距  Drawable[] drawables = this.getCompoundDrawables();   // 取得right位置的Drawable  // 即我们在布局文件中设置的androID:drawableRight  mRightDrawable = drawables[2];   // 设置焦点变化的监听  this.setonFocuschangelistener(new FocuschangelistenerImpl());  // 设置EditText文字变化的监听  this.addTextChangedListener(new TextWatcherImpl());  // 初始化时让右边clean图标不可见  setClearDrawableVisible(false);     }  @OverrIDe  public boolean ontouchEvent(MotionEvent event) {  switch (event.getAction()) {   //当点击松开时判断点击的位置。这里只进行了X轴方向的判断。   case MotionEvent.ACTION_UP:   //判断是否点击到了右边的图标区域   boolean isClean = (event.getX() > (getWIDth() - getTotalpaddingRight()))    && (event.getX() < (getWIDth() - getpaddingRight()));   if (isClean) {    //清除字符    setText("");   }   break;    default:   break;  }  return super.ontouchEvent(event);  }   private class FocuschangelistenerImpl implements OnFocuschangelistener {  @OverrIDe  public voID onFocusChange(VIEw v,boolean hasFocus) {   isHasFocus = hasFocus;   if (isHasFocus) {   boolean isVisible = getText().toString().length() >= 1;   setClearDrawableVisible(isVisible);   } else {   setClearDrawableVisible(false);   }  }   }   // 当输入结束后判断是否显示右边clean的图标  private class TextWatcherImpl implements TextWatcher {  @OverrIDe  public voID afterTextChanged(Editable s) {   //当有字符时为true   boolean isVisible = getText().toString().length() >= 1;   //显示右边的图标   setClearDrawableVisible(isVisible);  }   @OverrIDe  public voID beforeTextChanged(CharSequence s,int start,int count,int after) {   }   @OverrIDe  public voID onTextChanged(CharSequence s,int before,int count) {   }   }   // 隐藏或显示右边clean的图标  protected voID setClearDrawableVisible(boolean isVisible) {  Drawable rightDrawable;  if (isVisible) {   rightDrawable = mRightDrawable;  } else {   rightDrawable = null;  }  // 使用代码设置该控件right处的图标  setCompoundDrawables(getCompoundDrawables()[0],getCompoundDrawables()[1],rightDrawable,getCompoundDrawables()[3]);  }   // 显示动画  public voID setShakeAnimation() {  this.startAnimation(shakeAnimation(5));   }   // CycleTimes动画重复的次数  public Animation shakeAnimation(int CycleTimes) {  //设置偏移动画 其中new TranslateAnimation(0,10,10)四个值表示为 X坐标从0-->10,Y坐标从0-->10  Animation translateAnimation = new TranslateAnimation(0,10);  //设置动画次数  translateAnimation.setInterpolator(new CycleInterpolator(CycleTimes));  //设置动画间隔  translateAnimation.setDuration(1000);  return translateAnimation;  }  } 

其中需要注意的知识:

  1.Drawable[] drawables = this.getCompoundDrawables(); 得到此VIEw的 drawable. getCompoundDrawables()方法得到的有4个Drawable对象,分别对应此VIEw的左,上,右,下的边距

  2.boolean isClean = (event.getX() > (getWIDth() - getTotalpaddingRight()))&& (event.getX() < (getWIDth() - getpaddingRight()));  判断点击的区域是否为右边图标范围。其中event.getX()为点击的位置的X坐标大小。详细如下图所示:


 3.Animation translateAnimation = new TranslateAnimation(0,10); 设置偏移动画 其中new TranslateAnimation(0,Y坐标从0-->10

 4.this.setonFocuschangelistener(new FocuschangelistenerImpl());设置焦点变化的目的是为了更人性化。当焦点在此行并且有字符时才显示一键删除图标。不在此行时图标隐藏。

 5.this.addTextChangedListener(new TextWatcherImpl()); 设置text变化监听。new TextWatcher{}中有3个方法。分别是:

1).public voID beforeTextChanged(CharSequence s,int after) {}
2).public voID onTextChanged(CharSequence s,int count) {}
3).public voID afterTextChanged(Editable s) {}
我们只需要在afterTextChanged(){Editable s}{}中添加要实现的方法即可。当监听到text变化时,设置右边图标显示。

TextWatcher { @OverrIDe public voID afterTextChanged(Editable s) { //当有字符时为true boolean isVisible = getText().toString().length() >= 1; //显示右边的图标 setClearDrawableVisible(isVisible); }

验证码的实现过程:

思路:设置4个ImageVIEw。 首先随机生成4个10以内的数字存储在数组里。并且记录整个验证码。在利用Bitmap.createBitmap方法讲这4个数字转化为图片并且设置随机颜色。每个数字图片转化的时候在随机设置旋转角度使这4个数字图标倾斜一定的角度。 验证码就生成了。

验证验证码的过程只是模拟下: 将输入的验证码跟记录的验证码作比较。相同 提示正确,不同提示错误。并且重置验证码。

点击验证码图片区域也会重置验证码。
代码的注释很详细。上代码~~~~: 

package com.example.administrator.texttest;  import androID.graphics.Bitmap; import androID.graphics.Canvas; import androID.graphics.color; import androID.graphics.Matrix; import androID.support.v7.app.AppCompatActivity; import androID.os.Bundle; import androID.text.TextUtils; import androID.vIEw.Menu; import androID.vIEw.MenuItem; import androID.vIEw.VIEw; import androID.Widget.button; import androID.Widget.EditText; import androID.Widget.ImageVIEw; import androID.Widget.TextVIEw; import androID.Widget.Toast;  import java.util.Random;  public class MainActivity extends AppCompatActivity {  //登录按钮  private button btLogin;  //账户  private DeletableEditText userEditText;  //密码  private DeletableEditText psdEditText;    //验证码的数字文本  private TextVIEw tvHIDeA,ivNumD;  //验证码输入文本  private EditText etCheck;  //验证码的检测显示文本  private TextVIEw tvCheck;   //存储每个验证码的数字  private String numStrTmp = "";  //存储整个验证码的数字  private String numStr = "";   //存储验证码的数组  private int[] numArray = new int[4];  //存储颜色的数组  private int[] colorArray = new int[6];   @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentVIEw(R.layout.activity_main);  setupVIEws();   }   private voID setupVIEws() {  btLogin = (button) findVIEwByID(R.ID.bt_login);  btLogin.setonClickListener(new OnClickListenerImpl());  userEditText = (DeletableEditText) findVIEwByID(R.ID.tv_user);  psdEditText = (DeletableEditText) findVIEwByID(R.ID.tv_psd);    tvHIDeA = (TextVIEw) findVIEwByID(R.ID.tvHIDeA);  tvHIDeB = (TextVIEw) findVIEwByID(R.ID.tvHIDeB);  tvHIDeC = (TextVIEw) findVIEwByID(R.ID.tvHIDeC);  tvHIDeD = (TextVIEw) findVIEwByID(R.ID.tvHIDeD);   ivNumA = (ImageVIEw) findVIEwByID(R.ID.ivNumA);  ivNumB = (ImageVIEw) findVIEwByID(R.ID.ivNumB);  ivNumC = (ImageVIEw) findVIEwByID(R.ID.ivNumC);  ivNumD = (ImageVIEw) findVIEwByID(R.ID.ivNumD);   ivNumA.setonClickListener(new OnClickListenerImpl());  ivNumB.setonClickListener(new OnClickListenerImpl());  ivNumC.setonClickListener(new OnClickListenerImpl());  ivNumD.setonClickListener(new OnClickListenerImpl());     tvCheck = (TextVIEw) findVIEwByID(R.ID.tvCheck);  etCheck = (EditText) findVIEwByID(R.ID.etCheck);      setNum();      }  private voID setNum() {  initNum();  tvHIDeA.setText("" + numArray[0]);  tvHIDeA.setTextcolor(randomcolor());  tvHIDeB.setText("" + numArray[1]);  tvHIDeB.setTextcolor(randomcolor());  tvHIDeC.setText("" + numArray[2]);  tvHIDeC.setTextcolor(randomcolor());  tvHIDeD.setText("" + numArray[3]);  tvHIDeD.setTextcolor(randomcolor());    Matrix matrixA = new Matrix();  //重设矩阵  matrixA.reset();  matrixA.setRotate(randomAngle());  Bitmap bmNumA = Bitmap.createBitmap(getBitmapFromVIEw(tvHIDeA,20,50),50,matrixA,true);  ivNumA.setimageBitmap(bmNumA);   Matrix matrixB = new Matrix();  //重设矩阵  matrixB.reset();  matrixB.setRotate(randomAngle());  Bitmap bmNumB = Bitmap.createBitmap(getBitmapFromVIEw(tvHIDeB,matrixB,true);  ivNumB.setimageBitmap(bmNumB);   Matrix matrixC = new Matrix();  //重设矩阵  matrixC.reset();  matrixC.setRotate(randomAngle());  Bitmap bmNumC = Bitmap.createBitmap(getBitmapFromVIEw(tvHIDeC,matrixC,true);  ivNumC.setimageBitmap(bmNumC);   Matrix matrixD = new Matrix();  //重设矩阵  matrixD.reset();  matrixD.setRotate(randomAngle());  Bitmap bmNumD = Bitmap.createBitmap(getBitmapFromVIEw(tvHIDeD,matrixD,true);  ivNumD.setimageBitmap(bmNumD);   }   private Bitmap getBitmapFromVIEw(VIEw v,int wIDth,int height ) {  int wIDSpec = VIEw.MeasureSpec.makeMeasureSpec(wIDth,VIEw.MeasureSpec.EXACTLY);  int heiSpec = VIEw.MeasureSpec.makeMeasureSpec(height,VIEw.MeasureSpec.EXACTLY);  //重新绘制图片大小  v.measure(wIDSpec,heiSpec);  //  v.layout(0,wIDth,height);  Bitmap bitmap = Bitmap.createBitmap(wIDth,height,Bitmap.Config.ARGB_8888);   //画出图片  Canvas canvas = new Canvas(bitmap);  v.draw(canvas);   return bitmap;   }    //设置随机倾斜的角度  private int randomAngle() {    return 20*(new Random().nextInt(5)-new Random().nextInt(3));  }     //随机生成颜色  private int randomcolor() {  colorArray[0]=0xFF000000; //BLACK  colorArray[1] = 0xFFFF00FF; // magenta  colorArray[2] = 0xFFFF0000; // RED  colorArray[3] = 0xFF00FF00; // GREEN  colorArray[4] = 0xFF0000FF; // BLUE  colorArray[5] = 0xFF00FFFF; // CYAN  int randomColoID = new Random().nextInt(5);  return colorArray[randomColoID];      }  //初始化验证码  private voID initNum() {  numStr="";  numStrTmp="";  for (int i = 0; i < numArray.length; i++) {   //随机生成10以内数字   int numIntTmp = new Random().nextInt(10);   //保存各个验证码   numStrTmp = String.valueOf(numIntTmp);   //保存整个验证码   numStr = numStr+numStrTmp;   numArray[i] = numIntTmp;  }   }   private class OnClickListenerImpl implements VIEw.OnClickListener {  @OverrIDe  public voID onClick(VIEw v) {   //当点击的为登录按钮时   if(v==btLogin){   //判断账户字符是否为空,   if (TextUtils.isEmpty(userEditText.getText().toString())){    //为空时抖动提示    userEditText.setShakeAnimation();    Toast.makeText(MainActivity.this,"账户或密码不能为空",Toast.LENGTH_SHORT).show();   }   //判断密码字符是否为空   if (TextUtils.isEmpty(psdEditText.getText().toString())){    //为空时抖动提示    psdEditText.setShakeAnimation();    Toast.makeText(MainActivity.this,Toast.LENGTH_SHORT).show();   }    //验证输入的验证码是否正确   if(etCheck.getText().toString()!=null&&etCheck.getText().toString().trim().length()>0){    tvCheck.setVisibility(VIEw.VISIBLE);    if (numStr.equals(etCheck.getText().toString())){    tvCheck.setTextcolor(color.GREEN);    tvCheck.setText("验证码正确!");    }else{    tvCheck.setTextcolor(color.RED);    tvCheck.setText("验证码错误!");    etCheck.setText("");    setNum();    }   }   //如果OnClick不是登录按钮时只剩下验证码图片有监听事件。等同于点击验证码图片。改变验证码。   }else {   setNum();   tvCheck.setVisibility(VIEw.GONE);   }    }  } } 

需要注意的知识:
1.Bitmap.createBitmap(getBitmapFromVIEw(tvHIDeA,true); 
Bitmap.createBitmap(Bitmap source,int x,int y,int height,Matrix m,boolean filter)
Bitmap source:要从中截图的原始位图
int x:  起始x坐标
int y:起始y坐标
int wIDth:  要截的图的宽度
int height:要截的图的高度
boolean filter 当进行的不只是平移变换时,filter参数为true可以进行滤波处理,有助于改善新图像质量;flase时,计算机不做过滤处理。 

2.intwIDSpec = VIEw.MeasureSpec.makeMeasureSpec(wIDth,VIEw.MeasureSpec.EXACTLY);
  int heiSpec = VIEw.MeasureSpec.makeMeasureSpec(height,VIEw.MeasureSpec.EXACTLY);
 设置VIEw的宽和高。VIEw.MeasureSpec.EXACTLY 指的是设置为实际VIEw的大小。即前面的wIDth(height)为多大就为多大。

3.Bitmap.createBitmap(wIDth,Bitmap.Config.ARGB_8888); create一个图标。 

4.Canvas canvas =newCanvas(bitmap);
v.draw(canvas);  画出图片

5.v.measure(wIDSpec,heiSpec);
//v.layout(0,height);  重新绘制图片的大小。 

后面是运行时的图片:

当有输入时右边的一键删除图标显示、当失去焦点时一键删除图标隐藏、点击验证码更新验证码:

后面的就不详细图示了。

源码下载:http://xiazai.jb51.net/201610/yuanma/Androidlogin(jb51.net).rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的功能强大的登录界面Android实现代码全部内容,希望文章能够帮你解决功能强大的登录界面Android实现代码所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1147864.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存