Android(安卓)自定义数字键盘(三)自定义输入框
16lz
2021-01-24
Android 自定义数字键盘(一)
Android 自定义数字键盘(二)随机数字
Demo地址:https://github.com/danfengfirst/KeyDemo
这篇博客是在上面两篇博客的基础上修改的一个相对比较完整的demo,写完前面两篇我尝试使用过用pop弹出界面,但是焦点方面总是有问题,就参考了梁肖的思路,改用了Activity,为了思路清晰,没有给输入框自定义属性,效果演示如下(录的好像有点卡,动画效果跟点击的时候卡了,录制原因,正常运行不卡哈):
思路:
主要是三个方面:
1、自定义EidtText输入框,重写onTextChanged()方法来监听文本并进行刷新+圆点绘制
2、注意自定义的EditTextView获取焦点时隐藏键盘,显示自己定义的键盘,还有Editable的使用
3、对自定义键盘的点击事件监听回调,回调中分了两个方法一个插入数据,一个删除数据,通过方法名字应该看得出来。
//对按键的输入与删除事件进行监听 mKeyView.setOnKeyPressListener(new NumKeyView.OnKeyPressListener() { @Override public void onInertKey(String text) { //这里不可以直接使用mEditText来进行append,否则会显示数字 if (editable.length() < 6) { mPasswordStr.append(text); editable.append(text); } } @Override public void onDeleteKey() { if (editable.length() > 0) { int length = editable.length(); editable.delete(length - 1, length); mPasswordStr.delete(length - 1, length); } } });
代码
自定义输入框
代码很少也很容易理解
public class PassWordEdit extends EditText { //控件宽度与高度 private int mWidth; private int mHeight; private Paint mPaint; //输入密码长度 private int mPassWordLength; public PassWordEdit(Context context) { this(context, null); } public PassWordEdit(Context context, AttributeSet attrs) { super(context, attrs); //初始化 mPaint=new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(getResources().getColor(R.color.deepgray)); mPaint.setStrokeWidth(2); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //为了绘制矩形边框设置画笔为空心的 mPaint.setStyle(Paint.Style.STROKE); canvas.drawRect(new RectF(0+mPaint.getStrokeWidth(),0,mWidth-mPaint.getStrokeWidth(),mHeight),mPaint); mPaint.setStyle(Paint.Style.FILL); int width=(int)(mWidth/6.0); //绘制中间竖线 for (int i=1;i<=5;i++){ canvas.drawLine(width*i,0,width*i,mHeight,mPaint); } //绘制中间圆点 for (int j=0;j2+width*j,mHeight/2,5.0f,mPaint); } } @Override protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { super.onTextChanged(text, start, lengthBefore, lengthAfter); //进行监听,文本改变的时候刷新界面 if (text.length()!=mPassWordLength){ mPassWordLength=text.length(); } invalidate(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); setMeasuredDimension(mWidth, mHeight); }}
Activity调用
注意上面思路中提到的三点就可以
public class KeyDemo extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener { private PassWordEdit mEditText; private NumKeyView mKeyView; private Button mButtonEnsure; private ImageView mImageViewCancle; private StringBuffer mPasswordStr; private ToastUtil mToast; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.keyboard_pop); init(); } private void init() { mEditText = (PassWordEdit) findViewById(R.id.passWordEdit);//自定义密码输入框 mKeyView = (NumKeyView) findViewById(R.id.keyboardview);//自定义键盘 mButtonEnsure = (Button) findViewById(R.id.bt_ensure);//确定按钮 mImageViewCancle = (ImageView) findViewById(R.id.im_cancle);//取消按钮 mEditText.setInputType(InputType.TYPE_NULL);//隐藏键盘 mKeyView.setRandomKeyBoard(true);//设置随机数字键盘 mToast = new ToastUtil(getApplicationContext()); addListener(); mEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());//隐藏文本,不加这行代码会显示输入文本 } private void addListener() { mEditText.setOnFocusChangeListener(this); mButtonEnsure.setOnClickListener(this); mImageViewCancle.setOnClickListener(this); mEditText.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { showKeyBoard(); return false; } }); final Editable editable = mEditText.getText(); //对按键的输入与删除事件进行监听 mKeyView.setOnKeyPressListener(new NumKeyView.OnKeyPressListener() { @Override public void onInertKey(String text) { //这里不可以直接使用mEditText来进行append,否则会显示数字 if (editable.length() < 6) { mPasswordStr.append(text); editable.append(text); } } @Override public void onDeleteKey() { if (editable.length() > 0) { int length = editable.length(); editable.delete(length - 1, length); mPasswordStr.delete(length - 1, length); } } }); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.bt_ensure: if (mPasswordStr.length() <= 0) { mToast.showToastCenter("请输入有效密码"); } if (mPasswordStr.length() == 6) { Intent intent = new Intent(); intent.putExtra("data", mPasswordStr.toString()); setResult(RESULT_OK, intent); finish(); } break; case R.id.im_cancle: finish(); break; default: break; } } @Override public void onFocusChange(View view, boolean hasfocus) { mPasswordStr = new StringBuffer(); if (hasfocus) { hideSoftKeyBoard(); showKeyBoard(); } else { hideKeyBoard(); } } public void hideSoftKeyBoard() { InputMethodManager im = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE); im.hideSoftInputFromInputMethod(getCurrentFocus().getWindowToken(), InputMethodManager.RESULT_HIDDEN); } public void showKeyBoard() { if (mKeyView != null && (mKeyView.getVisibility() == View.INVISIBLE || mKeyView.getVisibility() == View.GONE)) { mKeyView.setVisibility(View.VISIBLE); } } public void hideKeyBoard() { if (mKeyView != null && (mKeyView.getVisibility() == View.VISIBLE)) { mKeyView.setVisibility(View.GONE); } }}
布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/transparent_half_half_half" android:gravity="bottom" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" android:padding="10dp"> <ImageView android:id="@+id/im_cancle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:src="@drawable/guanbixiao" /> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:text="请输入支付密码" android:textSize="24sp" /> <TextView android:id="@+id/tv_tip" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/tv_title" android:gravity="center_horizontal" android:text="您的手机不在常用地区登录,为保障您的资金安全,请输入支付密码" android:textColor="@color/colorAccent" android:textSize="22sp" /> <包名+PassWordEdit android:id="@+id/passWordEdit" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginTop="5dp" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_below="@+id/tv_tip" android:layout_weight="1" android:background="#ffffff" android:maxLength="6" android:textColor="@color/colorAccent" /> <Button android:id="@+id/bt_ensure" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/passWordEdit" android:layout_centerHorizontal="true" android:layout_marginTop="20dp" android:background="@drawable/btbg" android:text="确定" /> RelativeLayout> <包名+NumKeyView android:id="@+id/keyboardview" android:layout_width="match_parent" android:layout_height="wrap_content" android:focusable="true" android:focusableInTouchMode="true" android:keyBackground="@color/colorAccent" app:deleteDrawable="@drawable/keyboard_backspace" app:gbColor="#eeeeee" />LinearLayout>
其他部分
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void popkeyboard(View view){ Intent intent=new Intent(MainActivity.this,KeyDemo.class); startActivityForResult(intent,0x11); overridePendingTransition(R.anim.showanim,R.anim.dismissanim); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode==RESULT_OK){ String text=data.getExtras().getString("data"); ToastUtil toastUtil=new ToastUtil(getApplicationContext()); toastUtil.showToastCenter(text); } }}
动画(用的之前的)
show
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0" android:fromYDelta="100%" android:toXDelta="0" android:toYDelta="0" android:duration="1000" >translate>set>
dismiss
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"><translate android:toXDelta="0" android:fromXDelta="0" android:fromYDelta="0" android:toYDelta="100%" android:duration="1000" >translate>set>
更多相关文章
- 文本类控件(EditView 的介绍)
- android输入法中的imeoption
- 深度揭秘android摄像头的autoFocus-----循环自动聚焦的实现(Andro
- 2.Android开发---xml布局文件中的常见属性总结
- Android实现TextView中部分文字监听事件
- Android手机软键盘enter改为搜索
- Android:采用Google Suggest API 实现 AutoCompleteTextView的填
- Android开发中TextView文本过长滚动显示实现方法分析
- android避免弹出软键盘遮盖listview