安卓自定义密码编辑器

     首先呢?本文的源码是在github上的一位名叫jungerr的源码上改的,在此也很感谢他的文章。

     好了,回归这篇文章的主题。我们都知道微信支付和支付宝支付在输入六位输密码的时候的弹框特别漂亮,但安卓系统自带的editText就显得那么的“丑”,即使给他添加背景也无法做到这点。

    先贴代码的整体结构:




    下面开始讲解核心代码:

    1.首先先自定义一个类ImeDelBugFixedEditText继承自EditText,它是密码框内的每一个编辑框。

 

public class ImeDelBugFixedEditText extends EditText {

    private OnDelKeyEventListener delKeyEventListener;

    public ImeDelBugFixedEditText(Context context) {
        super(context);
    }

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

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

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        return new ZanyInputConnection(super.onCreateInputConnection(outAttrs), true);
    }

    private class ZanyInputConnection extends InputConnectionWrapper {

        public ZanyInputConnection(InputConnection target, boolean mutable) {
            super(target, mutable);
        }

        @Override
        public boolean sendKeyEvent(KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
                if (delKeyEventListener != null) {
                    delKeyEventListener.onDeleteClick();
                    return true;
                }
            }
            return super.sendKeyEvent(event);
        }


        @Override
        public boolean deleteSurroundingText(int beforeLength, int afterLength) {
            if (beforeLength == 1 && afterLength == 0) {
                return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)) && sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
            }

            return super.deleteSurroundingText(beforeLength, afterLength);
        }
    }

    public void setDelKeyEventListener(OnDelKeyEventListener delKeyEventListener) {
        this.delKeyEventListener = delKeyEventListener;
    }

    public interface OnDelKeyEventListener {

        void onDeleteClick();

    }

}

2.在定义一个类GridPasswordView继承自LinearLayout。这个类的主要是实现密码输入框,由于是自定义所以他能实现密码框的长度

自定义,框架颜色自定义,每个字的背景颜色自定义。

public class GPVActivity extends BaseActivity {
    String tag = "GPVActivity";
    private GridPasswordView ui, transformation, pwdtype, twiceInput;
    private Spinner gpvSpinner;
    private Switch gpvSwitch;

    private TextView tv;
    boolean isFirst = true;
    String firstPwd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gpv);
        initView();
        onPwdChangedTest();
        /*解决输入时键盘遮挡问题*/
//        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
    }


    private void initView() {
        findViewById(R.id.back_gpv).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        ui = (GridPasswordView) findViewById(R.id.gpv_customUi);
        transformation = (GridPasswordView) findViewById(R.id.gpv_transformation);
        pwdtype = (GridPasswordView) findViewById(R.id.gpv_passwordType);
        twiceInput = (GridPasswordView) findViewById(R.id.gpv_normail_twice);
        gpvSpinner = (Spinner) findViewById(R.id.pswtype_sp);
        gpvSpinner.setOnItemSelectedListener(itemListener);
        gpvSwitch = (Switch) findViewById(R.id.psw_visibility_switcher);
        gpvSwitch.setOnCheckedChangeListener(checkListener);
        tv= (TextView) findViewById(R.id.gpv_news);
    }

    /*设置是否显示密码*/
    CompoundButton.OnCheckedChangeListener checkListener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            Logs.v(tag + " 61 " + isChecked);
            ui.togglePasswordVisibility();
            transformation.togglePasswordVisibility();
            pwdtype.togglePasswordVisibility();
            twiceInput.togglePasswordVisibility();
        }
    };


    /*监听选择的方式*/
    AdapterView.OnItemSelectedListener itemListener = new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            switch (position) {
                case 0:
                    pwdtype.setPasswordType(PasswordType.NUMBER);
                    break;

                case 1:
                    pwdtype.setPasswordType(PasswordType.TEXT);
                    break;

                case 2:

                    pwdtype.setPasswordType(PasswordType.TEXTVISIBLE);
                    break;

                case 3:
                    pwdtype.setPasswordType(PasswordType.TEXTWEB);
                    break;
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            ToastUtil.showLong("请选中其中一种密码方式");
        }
    };


//在OnPasswordChangedListener中测试GridPasswordView.clearPassword()。需要输入密码两次,然后检查密码,如支付宝

    private void onPwdChangedTest() {
        twiceInput.setOnPasswordChangedListener(new GridPasswordView.OnPasswordChangedListener() {
            @Override
            public void onTextChanged(String psw) {
                if (psw.length() == 6 && isFirst) {
                    twiceInput.clearPassword();
                    isFirst = false;
                    firstPwd = psw;
                    tv.setText("请再输一次密码");
                } else if (psw.length() == 6 && !isFirst) {
                    if (psw.equals(firstPwd)) {
                        Log.d("lcb", tag + "  112  The password is: " + psw);
                        tv.setText("两次密码输入一样,为:"+psw);
                    } else {
                        Log.d("lcb", tag + "  114  password doesn't match the previous one, try again!");
                        tv.setText("密码两次输入不一致,请重试!");
                    }
                    twiceInput.clearPassword();
                    isFirst = true;
                }
            }

            @Override
            public void onInputFinish(String psw) {
                Logs.i(tag +" 124 "+psw);
            }
        });
    }
}

3.切记在value文件下的attr.xml(没有自己建)文件下定义些属性,不然安卓系统读取不到会报错喔! 大笑

   <!--++++++++++++  gridPasswordView的自定义属性 ++++++++++++++-->
    <declare-styleable name="gridPasswordView">

        <attr name="gpvTextColor" format="color|reference"/>文字颜色
        <attr name="gpvTextSize" format="dimension"/>文字大小

        <attr name="gpvLineColor" format="color"/>文字框边界颜色

        <attr name="gpvGridColor" format="color"/>文字框内部颜色

        <attr name="gpvLineWidth" format="dimension"/>文字框边界长度

        <attr name="gpvPasswordLength" format="integer"/>设定文字框几个
        <attr name="gpvPasswordTransformation" format="string"/>密码覆盖的文字

        <attr name="gpvPasswordType" format="enum">枚举,四种情况
            <enum name="numberPassword" value="0"/>
            <enum name="textPassword" value="1"/>
            <enum name="textVisiblePassword" value="2"/>
            <enum name="textWebPassword" value="3"/>
        </attr>

    </declare-styleable>

ps:特别提示,有个bug没解决。就是当你选0即numberPassword只能输入数字,在输入六位数的时候会自动跳转,选另外三个1,2,3即文字类型。英文字母(大写或小写)

也是ok的,中文一个字ok,但两个字及以上就无法自动跳到下一个edittext里全挤在同一个edittext。如果有哪位大神解决这个问题就私信我下。可怜


4.效果图



   源码下载地址:http://download.csdn.net/download/xxdw1992/10020922
    
        

    


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值