Android 自定义数字键盘(三)自定义输入框

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/danfengw/article/details/53897114

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;j<mPassWordLength;j++){
            canvas.drawCircle(width/2+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>
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页