Android自定义View示例(一)—带有删除按钮的EditText

MainActivity如下:

package cc.textview5;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.app.Activity;
/**
 * Demo描述:
 * 自定义控件实现带清除功能的EditText
 *
 * 学习资料:
 * http://blog.csdn.net/xiaanming/article/details/11066685
 *
 * Thank you very much
 */
public class MainActivity extends Activity {
    private CleanableEditText mUserNameCleanableEditText;
    private CleanableEditText mPassWordCleanableEditText;
    private Button mLoginButton;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		init();
	}

	private void init(){
		mUserNameCleanableEditText=(CleanableEditText) findViewById(R.id.userNameEditText);
		mPassWordCleanableEditText=(CleanableEditText) findViewById(R.id.passwordEditText);
		mLoginButton=(Button) findViewById(R.id.loginButton);
		mLoginButton.setOnClickListener(new OnClickListenerImpl());
	}

	private class OnClickListenerImpl implements OnClickListener {
		@Override
		public void onClick(View view) {
			if (TextUtils.isEmpty(mUserNameCleanableEditText.getText())) {
				mUserNameCleanableEditText.setShakeAnimation();
				Toast.makeText(MainActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
			}

			if (TextUtils.isEmpty(mPassWordCleanableEditText.getText())) {
				mPassWordCleanableEditText.setShakeAnimation();
				Toast.makeText(MainActivity.this, "请输入密码", Toast.LENGTH_SHORT).show();
			}
		}

	}

}

CleanableEditText如下:

package cc.textview5;

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;
/**
 * 在焦点变化时和输入内容发生变化时均要判断是否显示右边clean图标
 */
public class CleanableEditText extends EditText {
    private Drawable mRightDrawable;
    private boolean isHasFocus;

	public CleanableEditText(Context context) {
		super(context);
		init();
	}
	public CleanableEditText(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public CleanableEditText(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	private void init(){
		//getCompoundDrawables:
		//Returns drawables for the left, top, right, and bottom borders.
		Drawable [] drawables=this.getCompoundDrawables();

		//取得right位置的Drawable
		//即我们在布局文件中设置的android:drawableRight
        mRightDrawable=drawables[2];	

        //设置焦点变化的监听
        this.setOnFocusChangeListener(new FocusChangeListenerImpl());
        //设置EditText文字变化的监听
        this.addTextChangedListener(new TextWatcherImpl());
        //初始化时让右边clean图标不可见
        setClearDrawableVisible(false);
	}

	/**
	 * 当手指抬起的位置在clean的图标的区域
	 * 我们将此视为进行清除操作
	 * getWidth():得到控件的宽度
	 * event.getX():抬起时的坐标(改坐标是相对于控件本身而言的)
	 * getTotalPaddingRight():clean的图标左边缘至控件右边缘的距离
	 * getPaddingRight():clean的图标右边缘至控件右边缘的距离
	 * 于是:
	 * getWidth() - getTotalPaddingRight()表示:
	 * 控件左边到clean的图标左边缘的区域
	 * getWidth() - getPaddingRight()表示:
	 * 控件左边到clean的图标右边缘的区域
	 * 所以这两者之间的区域刚好是clean的图标的区域
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		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) {
			 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 start, int before,int count) {

		}

    }	

    //隐藏或者显示右边clean的图标
	protected void setClearDrawableVisible(boolean isVisible) {
		Drawable rightDrawable;
		if (isVisible) {
			rightDrawable = mRightDrawable;
		} else {
			rightDrawable = null;
		}
		//使用代码设置该控件left, top, right, and bottom处的图标
		setCompoundDrawables(getCompoundDrawables()[0],getCompoundDrawables()[1],
				             rightDrawable,getCompoundDrawables()[3]);
	} 

	// 显示一个动画,以提示用户输入
	public void setShakeAnimation() {
		this.setAnimation(shakeAnimation(5));
	}

	//CycleTimes动画重复的次数
	public Animation shakeAnimation(int CycleTimes) {
		Animation translateAnimation = new TranslateAnimation(0, 10, 0, 10);
		translateAnimation.setInterpolator(new CycleInterpolator(CycleTimes));
		translateAnimation.setDuration(1000);
		return translateAnimation;
	}

}

main.xml如下:

<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="20dip"
    android:paddingRight="20dip"
    >

    <cc.textview5.CleanableEditText
        android:id="@+id/userNameEditText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="username"
        android:layout_marginTop="30dip"
        android:drawableLeft="@drawable/icon_user"
        android:drawableRight="@drawable/clean_selector"
         />

     <cc.textview5.CleanableEditText
        android:id="@+id/passwordEditText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="password"
        android:password="true"
        android:layout_marginTop="100dip"
        android:drawableLeft="@drawable/account_icon"
        android:drawableRight="@drawable/clean_selector"
         />

     <Button
         android:id="@+id/loginButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Login"
        android:layout_marginTop="155dip"
         />

</RelativeLayout>



时间: 2024-09-26 20:47:14

Android自定义View示例(一)—带有删除按钮的EditText的相关文章

Android自定义View示例(四)—带有动画的Dialog

MainActivity如下: package cc.testview1; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * 自定义Dialog,在Dialog中有动画(旋转动画或者帧动画)效果 */ public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceStat

Android 带有删除按钮的EditText

MainActivity如下: package cc.textview5; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; import android.app.Activity;

Android实现带有删除按钮的EditText示例代码_Android

一.首先来看看效果 这是一个带有删除按钮的输入文本框, 需要新建一个类继承自EditText, 先把代码贴出来, 然后在解释: 示例代码如下: public class EditTextWithDel extends EditText { private final static String TAG = "EditTextWithDel"; private Drawable imgInable; private Context mContext; public EditTextWit

Android实现带有删除按钮的EditText示例代码

一.首先来看看效果 这是一个带有删除按钮的输入文本框, 需要新建一个类继承自EditText, 先把代码贴出来, 然后在解释: 示例代码如下: public class EditTextWithDel extends EditText { private final static String TAG = "EditTextWithDel"; private Drawable imgInable; private Context mContext; public EditTextWit

Android自定义View制作动态炫酷按钮实例解析_Android

普通按钮也就那么几种样式,看着都审美疲劳,先放效果图:   你会不会以为这个按钮是集结了很多动画的产物,我告诉你,并没有.所有的实现都是基于自定义View,采用最底层的onDraw一点一点的画出来的.没有采用一丁点的动画.虽然演示时间很短,但是要完成这么多变化,还是挺吃力. 首先讲解用法:  public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceStat

Android自定义View示例(二)—滑动开关

MainActivity如下: package cc.testview3; import cc.testview3.SwitchView.SwitchChangedListener; import android.os.Bundle; import android.widget.Toast; import android.app.Activity; /** * Demo描述: * 自定义View实现滑动开关 * * 测试设备: * 分辨率为480x854 */ public class Main

Android自定义View制作动态炫酷按钮实例解析

普通按钮也就那么几种样式,看着都审美疲劳,先放效果图: 你会不会以为这个按钮是集结了很多动画的产物,我告诉你,并没有.所有的实现都是基于自定义View,采用最底层的onDraw一点一点的画出来的.没有采用一丁点的动画.虽然演示时间很短,但是要完成这么多变化,还是挺吃力. 首先讲解用法: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState)

Android自定义View获取注册验证码倒计时按钮_Android

在Android开发中,我们不可避免的会做到注册功能,而现在的注册大多数都是用手机去注册的,那么注册的时候都会要求用获取验证码的方式去验证,我们接下来就来实战一下自定义获取验证码倒计时按钮: 1.先看效果图 2.我们涉及到的变量 //倒计时时长,可设置 /** * 倒计时时长,默认倒计时时间60秒: */ private long length = 60 * 1000; //在点击按钮之前按钮所显示的文字 /** * 在点击按钮之前按钮所显示的文字,默认是获取验证码 */ private Str

Android自定义View获取注册验证码倒计时按钮

在Android开发中,我们不可避免的会做到注册功能,而现在的注册大多数都是用手机去注册的,那么注册的时候都会要求用获取验证码的方式去验证,我们接下来就来实战一下自定义获取验证码倒计时按钮: 1.先看效果图 2.我们涉及到的变量 //倒计时时长,可设置 /** * 倒计时时长,默认倒计时时间60秒: */ private long length = 60 * 1000; //在点击按钮之前按钮所显示的文字 /** * 在点击按钮之前按钮所显示的文字,默认是获取验证码 */ private Str