现在市面上,啥都要仿IOS,感觉Android 比IOS低几级.都要按照ios的方式去做,哎

今天给大家带来一个很实用的小控件ClearEditText,就是在Android系统的输入框右边加入一个小图标,点击小图标可以清除输入框里面的内容,IOS上面直接设置某个属性就可以实现这一功能,但是Android原生EditText不具备此功能,所以要想实现这一功能我们需要重写EditText,接下来就带大家来实现这一小小的功能

我们知道,我们可以为我们的输入框在上下左右设置图片,所以我们可以利用属性android:drawableRight设置我们的删除小图标,如图


我这里设置了左边和右边的图片,如果我们能为右边的图片设置监听,点击右边的图片清除输入框的内容并隐藏删除图标,这样子这个小功能就迎刃而解了,可是Android并没有给允许我们给右边小图标加监听的功能,这时候你是不是发现这条路走不通呢,其实不是,我们可能模拟点击事件,用输入框的的onTouchEvent()方法来模拟,

当我们触摸抬起(就是ACTION_UP的时候)的范围  大于输入框左侧到清除图标左侧的距离,小与输入框左侧到清除图片右侧的距离,我们则认为是点击清除图片,当然我这里没有考虑竖直方向,只要给清除小图标就上了监听,其他的就都好处理了,我先把代码贴上来,在讲解下

[java]  view plain  copy
  1. package com.example.clearedittext;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.drawable.Drawable;  
  5. import android.text.Editable;  
  6. import android.text.TextWatcher;  
  7. import android.util.AttributeSet;  
  8. import android.view.MotionEvent;  
  9. import android.view.View;  
  10. import android.view.View.OnFocusChangeListener;  
  11. import android.view.animation.Animation;  
  12. import android.view.animation.CycleInterpolator;  
  13. import android.view.animation.TranslateAnimation;  
  14. import android.widget.EditText;  
  15.   
  16. public class ClearEditText extends EditText implements    
  17.         OnFocusChangeListener, TextWatcher {   
  18.     /** 
  19.      * 删除按钮的引用 
  20.      */  
  21.     private Drawable mClearDrawable;   
  22.     /** 
  23.      * 控件是否有焦点 
  24.      */  
  25.     private boolean hasFoucs;  
  26.    
  27.     public ClearEditText(Context context) {   
  28.         this(context, null);   
  29.     }   
  30.    
  31.     public ClearEditText(Context context, AttributeSet attrs) {   
  32.         //这里构造方法也很重要,不加这个很多属性不能再XML里面定义  
  33.         this(context, attrs, android.R.attr.editTextStyle);   
  34.     }   
  35.       
  36.     public ClearEditText(Context context, AttributeSet attrs, int defStyle) {  
  37.         super(context, attrs, defStyle);  
  38.         init();  
  39.     }  
  40.       
  41.       
  42.     private void init() {   
  43.         //获取EditText的DrawableRight,假如没有设置我们就使用默认的图片  
  44.         mClearDrawable = getCompoundDrawables()[2];   
  45.         if (mClearDrawable == null) {   
  46. //          throw new NullPointerException("You can add drawableRight attribute in XML");  
  47.             mClearDrawable = getResources().getDrawable(R.drawable.delete_selector);   
  48.         }   
  49.           
  50.         mClearDrawable.setBounds(00, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());   
  51.         //默认设置隐藏图标  
  52.         setClearIconVisible(false);   
  53.         //设置焦点改变的监听  
  54.         setOnFocusChangeListener(this);   
  55.         //设置输入框里面内容发生改变的监听  
  56.         addTextChangedListener(this);   
  57.     }   
  58.    
  59.    
  60.     /** 
  61.      * 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件 
  62.      * 当我们按下的位置 在  EditText的宽度 - 图标到控件右边的间距 - 图标的宽度  和 
  63.      * EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向就没有考虑 
  64.      */  
  65.     @Override   
  66.     public boolean onTouchEvent(MotionEvent event) {  
  67.         if (event.getAction() == MotionEvent.ACTION_UP) {  
  68.             if (getCompoundDrawables()[2] != null) {  
  69.   
  70.                 boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight())  
  71.                         && (event.getX() < ((getWidth() - getPaddingRight())));  
  72.                   
  73.                 if (touchable) {  
  74.                     this.setText("");  
  75.                 }  
  76.             }  
  77.         }  
  78.   
  79.         return super.onTouchEvent(event);  
  80.     }  
  81.    
  82.     /** 
  83.      * 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏 
  84.      */  
  85.     @Override   
  86.     public void onFocusChange(View v, boolean hasFocus) {   
  87.         this.hasFoucs = hasFocus;  
  88.         if (hasFocus) {   
  89.             setClearIconVisible(getText().length() > 0);   
  90.         } else {   
  91.             setClearIconVisible(false);   
  92.         }   
  93.     }   
  94.    
  95.    
  96.     /** 
  97.      * 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去 
  98.      * @param visible 
  99.      */  
  100.     protected void setClearIconVisible(boolean visible) {   
  101.         Drawable right = visible ? mClearDrawable : null;   
  102.         setCompoundDrawables(getCompoundDrawables()[0],   
  103.                 getCompoundDrawables()[1], right, getCompoundDrawables()[3]);   
  104.     }   
  105.        
  106.       
  107.     /** 
  108.      * 当输入框里面内容发生变化的时候回调的方法 
  109.      */  
  110.     @Override   
  111.     public void onTextChanged(CharSequence s, int start, int count,   
  112.             int after) {   
  113.                 if(hasFoucs){  
  114.                     setClearIconVisible(s.length() > 0);  
  115.                 }  
  116.     }   
  117.    
  118.     @Override   
  119.     public void beforeTextChanged(CharSequence s, int start, int count,   
  120.             int after) {   
  121.            
  122.     }   
  123.    
  124.     @Override   
  125.     public void afterTextChanged(Editable s) {   
  126.            
  127.     }   
  128.       
  129.      
  130.     /** 
  131.      * 设置晃动动画 
  132.      */  
  133.     public void setShakeAnimation(){  
  134.         this.setAnimation(shakeAnimation(5));  
  135.     }  
  136.       
  137.       
  138.     /** 
  139.      * 晃动动画 
  140.      * @param counts 1秒钟晃动多少下 
  141.      * @return 
  142.      */  
  143.     public static Animation shakeAnimation(int counts){  
  144.         Animation translateAnimation = new TranslateAnimation(01000);  
  145.         translateAnimation.setInterpolator(new CycleInterpolator(counts));  
  146.         translateAnimation.setDuration(1000);  
  147.         return translateAnimation;  
  148.     }  
  149.    
  150.    
  151. }  

  • setClearIconVisible()方法,设置隐藏和显示清除图标的方法,我们这里不是调用setVisibility()方法,setVisibility()这个方法是针对View的,我们可以调用setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom)来设置上下左右的图标

  • setOnFocusChangeListener(this) 为输入框设置焦点改变监听,如果输入框有焦点,我们判断输入框的值是否为空,为空就隐藏清除图标,否则就显示
  • addTextChangedListener(this) 为输入框设置内容改变监听,其实很简单呢,当输入框里面的内容发生改变的时候,我们需要处理显示和隐藏清除小图标,里面的内容长度不为0我们就显示,否是就隐藏,但这个需要输入框有焦点我们才改变显示或者隐藏,为什么要需要焦点,比如我们一个登陆界面,我们保存了用户名和密码,在登陆界面onCreate()的时候,我们把我们保存的密码显示在用户名输入框和密码输入框里面,输入框里面内容发生改变,导致用户名输入框和密码输入框里面的清除小图标都显示了,这显然不是我们想要的效果,所以加了一个是否有焦点的判断
  • setShakeAnimation(),这个方法是输入框左右抖动的方法,之前我在某个应用看到过类似的功能,当用户名错误,输入框就在哪里抖动,感觉挺好玩的,其实主要是用到一个移动动画,然后设置动画的变化率为正弦曲线


接下来我们来使用它,Activity的布局,两个我们自定义的输入框,一个按钮

[html]  view plain  copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#95CAE4">  
  6.   
  7.   
  8.     <com.example.clearedittext.ClearEditText  
  9.         android:id="@+id/username"  
  10.         android:layout_marginTop="60dp"  
  11.         android:layout_width="fill_parent"  
  12.         android:background="@drawable/login_edittext_bg"   
  13.         android:drawableLeft="@drawable/icon_user"  
  14.         android:layout_marginLeft="10dip"  
  15.         android:layout_marginRight="10dip"  
  16.         android:singleLine="true"  
  17.         android:drawableRight="@drawable/delete_selector"  
  18.         android:hint="输入用户名"  
  19.         android:layout_height="wrap_content" >  
  20.   
  21.     com.example.clearedittext.ClearEditText>  
  22.   
  23.     <com.example.clearedittext.ClearEditText  
  24.         android:id="@+id/password"  
  25.         android:layout_marginLeft="10dip"  
  26.         android:layout_marginRight="10dip"  
  27.         android:layout_marginTop="10dip"  
  28.         android:drawableLeft="@drawable/account_icon"  
  29.         android:hint="输入密码"  
  30.         android:singleLine="true"  
  31.         android:password="true"  
  32.         android:drawableRight="@drawable/delete_selector"  
  33.         android:layout_width="fill_parent"  
  34.         android:layout_height="wrap_content"  
  35.         android:layout_below="@id/username"  
  36.         android:background="@drawable/login_edittext_bg" >  
  37.     com.example.clearedittext.ClearEditText>  
  38.   
  39.     <Button  
  40.         android:id="@+id/login"  
  41.         android:layout_width="fill_parent"  
  42.         android:layout_height="wrap_content"  
  43.         android:layout_marginLeft="10dip"  
  44.         android:layout_marginRight="10dip"  
  45.         android:background="@drawable/login_button_bg"  
  46.         android:textSize="18sp"  
  47.         android:textColor="@android:color/white"  
  48.         android:layout_below="@+id/password"  
  49.         android:layout_marginTop="25dp"  
  50.         android:text="登录" />  
  51.   
  52. RelativeLayout>  
然后就是界面代码的编写,主要是测试输入框左右晃动而已,比较简单

[java]  view plain  copy
  1. package com.example.clearedittext;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.text.TextUtils;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.Toast;  
  10.   
  11. public class MainActivity extends Activity {  
  12.     private Toast mToast;  
  13.   
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.activity_main);  
  18.           
  19.         final ClearEditText username = (ClearEditText) findViewById(R.id.username);  
  20.         final ClearEditText password = (ClearEditText) findViewById(R.id.password);  
  21.           
  22.         ((Button) findViewById(R.id.login)).setOnClickListener(new OnClickListener() {  
  23.               
  24.             @Override  
  25.             public void onClick(View v) {  
  26.                 if(TextUtils.isEmpty(username.getText())){  
  27.                     //设置晃动  
  28.                     username.setShakeAnimation();  
  29.                     //设置提示  
  30.                     showToast("用户名不能为空");  
  31.                     return;  
  32.                 }  
  33.                   
  34.                 if(TextUtils.isEmpty(password.getText())){  
  35.                     password.setShakeAnimation();  
  36.                     showToast("密码不能为空");  
  37.                     return;  
  38.                 }  
  39.             }  
  40.         });  
  41.     }  
  42.       
  43.     /** 
  44.      * 显示Toast消息 
  45.      * @param msg 
  46.      */  
  47.     private void showToast(String msg){  
  48.         if(mToast == null){  
  49.             mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);  
  50.         }else{  
  51.             mToast.setText(msg);  
  52.         }  
  53.         mToast.show();  
  54.     }  
  55.   
  56.   
  57. }  

运行项目,如图,悲剧,没有动画效果,算了就这样子吧,你是不是也想把它加到你的项目当中去呢,赶紧吧!

更多相关文章

  1. Android操作JNI函数以及复杂对象传递
  2. Activity 生命周期(一)
  3. Android(安卓)组件系列-----Activity保存状态
  4. android: 接收和发送短信
  5. Android自学笔记-14-意图(Intent)
  6. Android(安卓)程序在系统中如何完成启动
  7. Activity从屏幕底部滑出、滑入、处理黑色背景和状态栏
  8. Android之AsyncTask的用法
  9. Android之ViewStub的简单使用

随机推荐

  1. android 的短信数据库的读取
  2. Android(安卓)Studio逆向分析APK(Analyse
  3. Android(安卓)EditText inputType属性
  4. Android中的singleLine(单行显示)和ellipsi
  5. android xml常规布局属性
  6. android国际化操作
  7. Android(安卓)编程下 Managing Your App'
  8. Android(安卓)五大布局
  9. react-native 热更新(android)
  10. Android图形层叠 – Layer-list