English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Code d'implémentation d'une interface de connexion puissante pour Android

Préambule

     Une bonne application nécessite une interface de connexion avec une bonne expérience utilisateur. De nos jours, de nombreuses interfaces de connexion des applications ont des fonctionnalités telles que la suppression d'un nom d'utilisateur et d'un mot de passe en un clic, un avertissement lorsque le nom d'utilisateur et le mot de passe sont vides, et la nécessité de saisir un code de vérification. En lisant les articles des grands experts de csdn, j'ai pensé à écrire une interface de connexion pour apprendre. Beaucoup de choses sont参考 d'autres articles, combinées. Sans plus attendre, voyons maintenant comment cela est réalisé. 

ps: Parce que je n'ai pas envie de gratter des images, l'icône du programme est très laid.
Illustration de l'exécution du programme :

Le fichier de conception n'a pas de difficulté.

<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="Saisissez le nom d'utilisateur" 
 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="Saisissez le mot de passe" 
 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> 

Ensuite, charger des fichiers de conception et initialiser des contrôles.

//bouton de connexion 
 private Button btLogin; 
 //compte 
 private DeletableEditText userEditText; 
 //mot de passe 
 private DeletableEditText psdEditText; 
 //texte numérique du captcha 
 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(); 

Processus de mise en œuvre de l'EditText personnalisé :

Planification :Définir deux EidtText, dans chacun de ces EidtText définir des icônes. L'icône de gauche indique l'icône de compte et de mot de passe, et l'icône de droite est l'icône de suppression en un clic. Comme les icônes dans l'EditText n'ont pas d'événement onClick, pour réaliser l'effet de suppression en un clic, il faut utiliser la méthode de rappel OnTouchEvent pour écouter les événements de clic et réaliser la suppression en un clic. Lorsque le compte et le mot de passe ne contiennent pas de caractères, l'icône de suppression en un clic à droite est définie comme cachée, et lorsqu'il y a des caractères, l'icône est définie comme visible. Lorsque vous cliquez sur la gamme de l'icône de droite, supprimez les caractères de la ligne en cours. Cela permet de réaliser la suppression en un clic. De plus, lorsque le compte et le mot de passe sont vides et que vous devez vous connecter, ces deux lignes tremblent pour indiquer un avertissement.
Pas de bavardage, passons directement aux commentaires de code, ils sont clairs.

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; 
/** 
 * Créé par l'Administrateur le 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, attrs, defStyleAttr); 
 setupViews(); 
 } 
 private void setupViews() { 
 //Obtenir les marges supérieure, inférieure, gauche et droite de la vue 
 Drawable[] drawables = this.getCompoundDrawables(); 
 // Obtenir le Drawable à la position right 
 // C'est ce que nous avons configuré dans le fichier de mise en page : android:drawableRight 
 mRightDrawable = drawables[2; 
 // Définir l'écouteur de changement de focus 
 this.setOnFocusChangeListener(new FocusChangeListenerImpl()); 
 // Définir l'écouteur de modification de texte EditText 
 this.addTextChangedListener(new TextWatcherImpl()); 
 // Au démarrage, rendez l'icône de nettoyage à droite invisible 
 setClearDrawableVisible(false); 
 } 
 @Override 
 public boolean onTouchEvent(MotionEvent event) { 
 switch (event.getAction()) { 
  //Lorsque vous relâchez le clic, vérifiez l'emplacement du clic. Ici, seules les directions de l'axe X sont jugées. 
  case MotionEvent.ACTION_UP: 
  //vérifiez si vous avez cliqué sur la zone d'icône à droite 
  boolean isClean = (event.getX() > (getWidth() - getTotalPaddingRight())) 
   && (event.getX() < (getWidth() - getPaddingRight())); 
  if (isClean) { 
   //Effacer les caractères 
   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); 
  } 
 } 
 } 
 // Lorsque l'entrée est terminée, vérifiez si l'icône de nettoyage à droite doit être affichée 
 private class TextWatcherImpl implements TextWatcher { 
 @Override 
 public void afterTextChanged(Editable s) { 
  //Lorsqu'il y a des caractères, c'est true 
  boolean isVisible = getText().toString().length() >= 1; 
  //Afficher l'icône de droite 
  setClearDrawableVisible(isVisible); 
 } 
 @Override 
 public void beforeTextChanged(CharSequence s, int start, int count, 
     int after) { 
 } 
 @Override 
 public void onTextChanged(CharSequence s, int start, int before, 
     int count) { 
 } 
 } 
 // Masquer ou afficher l'icône de clean à droite 
 protected void setClearDrawableVisible(boolean isVisible) { 
 Drawable rightDrawable; 
 if (isVisible) { 
  rightDrawable = mRightDrawable; 
 } else { 
  rightDrawable = null; 
 } 
 // Utiliser le code pour définir l'icône à droite de ce contrôle 
 setCompoundDrawables(getCompoundDrawables()[0], 
  getCompoundDrawables()[1], rightDrawable, 
  getCompoundDrawables()[3 
 } 
 // Afficher l'animation 
 public void setShakeAnimation() { 
 this.startAnimation(shakeAnimation(5)); 
 } 
 // CycleTimes, le nombre de répétitions de l'animation 
 public Animation shakeAnimation(int CycleTimes) { 
 //Définir l'animation de déplacement, où new TranslateAnimation(0,10,0,10) pour représenter les quatre valeurs : l'axe des X commence à 0-->10, l'axe des Y commence à 0-->10 
 Animation translateAnimation = new TranslateAnimation(0, 10, 0, 10); 
 //Définir le nombre de répétitions de l'animation 
 translateAnimation.setInterpolator(new CycleInterpolator(CycleTimes)); 
 //Définir l'intervalle de l'animation 
 translateAnimation.setDuration(1000); 
 return translateAnimation; 
 } 
} 

Points à noter :

  1.Drawable[] drawables = this.getCompoundDrawables(); cela permet d'obtenir les drawable. getCompoundDrawables() retourne4un objet Drawable, correspondant respectivement aux marges gauche, haute, droite et basse de ce View

  2.boolean isClean = (event.getX() > (getWidth() - getTotalPaddingRight())) && (event.getX() < (getWidth() - getPaddingRight())); Juger si la zone cliquée est la portée de l'icône de droite. Dans ce cas, event.getX() est la taille de la coordonnée X de la position de clic. Détails comme dans l'image suivante :


 3.Animation translateAnimation = new TranslateAnimation(0, 10, 0, 10); Configurer l'animation de déplacement. new TranslateAnimation(0,10,0,10) pour représenter les quatre valeurs : l'axe des X commence à 0-->10, l'axe des Y commence à 0-->10

 4.this.setOnFocusChangeListener(new FocusChangeListenerImpl()); L'objectif de la modification de la focalisation est de rendre cela plus humain. Seulement lorsque le focus est sur cette ligne et qu'il y a des caractères, l'icône d'effacement d'un clic est affichée. Sinon, l'icône est cachée.

 5.this.addTextChangedListener(new TextWatcherImpl()); Configurer l'écouteur de changement de texte. new TextWatcher{} contient3méthodes. Ils sont respectivement :

1)。public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
2)。public void onTextChanged(CharSequence s, int start, int before, int count) {}
3)。public void afterTextChanged(Editable s) {}
Nous n'avons besoin que d'ajouter la méthode à réaliser dans afterTextChanged(){Editable s}{} pour cela. Lorsque nous détectons une variation de texte, nous définissons l'icône de droite pour s'afficher.

TextWatcher {
 @Override
 public void afterTextChanged(Editable s) {
 //Lorsqu'il y a des caractères, c'est true
 boolean isVisible = getText().toString().length() >= 1;
 //Afficher l'icône de droite
 setClearDrawableVisible(isVisible);
 }

CaptchaLe processus d'implémentation :

Planification :Configurer4ImageView. Premièrement, générer aléatoirement4un10Les nombres à l'intérieur sont stockés dans un tableau. Et enregistrer tout le captcha. En utilisant la méthode createBitmap de Bitmap pour parler de cela4Les nombres sont convertis en images et les couleurs sont définies aléatoirement. Chaque image de nombre est convertie en rotant aléatoirement l'angle de rotation }}4Les icônes numériques sont inclinées d'un certain angle. Le captcha est généré.

Le processus de vérification du captcha est simplement simulé : comparez le captcha entré avec le captcha enregistré. Si ils sont identiques, indiquez que c'est correct, sinon indiquez que c'est incorrect et réinitialisez le captcha.

Cliquez sur la zone de l'image du captcha pour réinitialiser le captcha également.
Les commentaires du code sont très détaillés. Voici le code ~~~~ : 

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 { 
 //bouton de connexion 
 private Button btLogin; 
 //compte 
 private DeletableEditText userEditText; 
 //mot de passe 
 private DeletableEditText psdEditText; 
 //texte numérique du captcha 
 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(); 
 } 
 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(); 
 //Réinitialiser la matrice 
 matrixA.reset(); 
 matrixA.setRotate(randomAngle()); 
 Bitmap bmNumA = Bitmap.createBitmap(getBitmapFromView(tvHideA,20,50),0,0,20,50,matrixA,true); 
 ivNumA.setImageBitmap(bmNumA); 
 Matrix matrixB = new Matrix(); 
 //Réinitialiser la matrice 
 matrixB.reset(); 
  
 Bitmap bmNumB = Bitmap.createBitmap(getBitmapFromView(tvHideB,20,50),0,0,20,50,matrixB,true); 
 ivNumB.setImageBitmap(bmNumB); 
 Matrix matrixC = new Matrix(); 
 //Réinitialiser la matrice 
 matrixC.reset(); 
  
 Bitmap bmNumC = Bitmap.createBitmap(getBitmapFromView(tvHideC,20,50),0,0,20,50,matrixC,true); 
 ivNumC.setImageBitmap(bmNumC); 
 Matrix matrixD = new Matrix(); 
 //Réinitialiser la matrice 
 matrixD.reset(); 
  
 Bitmap bmNumD = Bitmap.createBitmap(getBitmapFromView(tvHideD,20,50),0,0,20,50,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); 
 //Redéfinir la taille de l'image 
 v.measure(widSpec, heiSpec); 
 // 
 v.layout(0, 0, width, height); 
 Bitmap bitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888); 
 //Dessiner l'image 
 Canvas canvas = new Canvas(bitmap); 
 v.draw(canvas); 
 return bitmap; 
 } 
 //Définir un angle d'inclinaison aléatoire 
 private int randomAngle() { 
 return}} 20*(new Random().nextInt(5)-new Random().nextInt(3)); 
 } 
 //générer une couleur au hasard 
 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]; 
 } 
 //initialiser le code de vérification 
 private void initNum() { 
 numStr=""; 
 numStrTmp=""; 
 for (int i = 0; i < numArray.length; i++) { 
  //généré au hasard10numéro à l'intérieur 
  int numIntTmp = new Random().nextInt(10); 
  //enregistrer chaque code de vérification 
  numStrTmp = String.valueOf(numIntTmp); 
  //enregistrer tout le code de vérification 
  numStr = numStr+numStrTmp; 
  numArray[i] = numIntTmp; 
 } 
 } 
 private class OnClickListenerImpl implements View.OnClickListener { 
 @Override 
 public void onClick(View v) { 
  //quand le bouton cliqué est le bouton de connexion 
  if(v==btLogin){ 
  //vérifier si le caractère du compte est vide, 
  if (TextUtils.isEmpty(userEditText.getText().toString())){ 
   //si vide, indication de secousse 
   userEditText.setShakeAnimation(); 
   Toast.makeText(MainActivity.this,"Le compte ou le mot de passe ne peut pas être vide",Toast.LENGTH_SHORT).show(); 
  } 
  //vérifier si le caractère du mot de passe est vide 
  if (TextUtils.isEmpty(psdEditText.getText().toString())){ 
   //si vide, indication de secousse 
   psdEditText.setShakeAnimation(); 
   Toast.makeText(MainActivity.this,"Le compte ou le mot de passe ne peut pas être vide",Toast.LENGTH_SHORT).show(); 
  } 
  //Vérifier si le code de vérification entré est correct 
  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("Code de vérification correct !"); 
   }else{ 
   tvCheck.setTextColor(Color.RED); 
   tvCheck.setText("Code de vérification incorrect !"); 
   etCheck.setText(""); 
   setNum(); 
   } 
  } 
  //Si OnClick n'est pas le bouton de connexion, il ne reste que l'image de code de vérification qui a un événement d'écoute. Équivalent à cliquer sur l'image de code de vérification. Changer le code de vérification. 
  }else { 
  setNum(); 
  tvCheck.setVisibility(View.GONE); 
  } 
 } 
 } 
} 

Connaissances à noter :
1.Bitmap.createBitmap(getBitmapFromView(tvHideA,20,50),0,0,20,50,matrixA,true); 
Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)
Bitmap source : le bitmap original à partir duquel l'image est coupée
int x : coordonnée x de départ
int y : coordonnée y de départ
int width : la largeur de l'image à couper
int height : la hauteur de l'image à couper
boolean filter lors de la transformation de déplacement, si le paramètre filter est true, le traitement de filtrage peut être effectué, ce qui aide à améliorer la qualité de l'image nouvelle;false, l'ordinateur ne fait pas de traitement de filtrage. 

2.intwidSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
  int heiSpec = View.MeasureSpec.makeMeasureSpec(height,View.MeasureSpec.EXACTLY);
 Définir la largeur et la hauteur de la Vue. View.MeasureSpec.EXACTLY signifie que la taille est définie sur la taille réelle de la Vue. C'est-à-dire que la taille de width(height) précédente est aussi grande que possible.

3.Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888); Créer une icône. 

4.Canvas canvas =newCanvas(bitmap);
.v.draw(canvas); Dessiner l'image

5.v.measure(widSpec, heiSpec);
//v.layout(0,0, width, height); Redessiner la taille de l'image. 

Voici les images du runtime :

Lorsque l'utilisateur saisit quelque chose, l'icône de suppression rapide de droite s'affiche, et l'icône de suppression rapide disparaît lorsque l'utilisateur perd le focus. Cliquez sur le captcha pour mettre à jour le captcha :

Les détails suivants ne seront pas illustrés en détail.

Téléchargement de code source :http://xiazai.jb51.net/201610/yuanma/Androidlogin(jb51.net).rar

Voici la fin de cet article, j'espère qu'il vous sera utile dans vos études, et j'espère que vous soutiendrez également le tutoriel de cri.

Déclaration : le contenu de cet article est extrait du réseau, propriété de ses auteurs respectifs, contribué et téléchargé par les utilisateurs d'Internet. Ce site ne détient pas de droits de propriété, n'a pas été édité par l'homme, et n'assume aucune responsabilité juridique. Si vous trouvez du contenu suspect de violation de droits d'auteur, veuillez envoyer un e-mail à : notice#oldtoolbag.com (veuillez remplacer # par @ lors de l'envoi d'un e-mail pour signaler une violation, et fournir des preuves pertinentes. Une fois confirmée, ce site supprimera immédiatement le contenu suspect de violation de droits d'auteur.)

Vous pourriez aussi aimer