本文實例為大家分享了Android實現(xiàn)微信支付密碼輸入框的具體代碼,供大家參考,具體內(nèi)容如下
創(chuàng)新互聯(lián)建站成立于2013年,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都做網(wǎng)站、成都網(wǎng)站制作網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元立山做網(wǎng)站,已為上家服務(wù),為立山各地企業(yè)和個人服務(wù),聯(lián)系電話:18982081108
效果圖
項目中使用到了支付密碼功能,其實這類界面是比較常用的,涉及支付密碼的輸入的一般都會用到對的,所以單獨地把這部分抽取出來,有需要的朋友可以拿去用哈!
效果就是支付,彈出密碼框,輸入密碼,這個過程密碼不可見,并且提供一個輸入完畢的監(jiān)聽!
這個彈出層呢,其實就是一個DialogFragment,邏輯封裝在其內(nèi)部
一.彈出層進出動畫 (anim文件)
push_bottom_in.xml
<?xml version="1.0" encoding="utf-8"?>
push_bottom_out.xml
<?xml version="1.0" encoding="utf-8"?>
二.drawable資源
selector_item_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
鍵盤的點擊效果
shape_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
彈出框樣式
三.mipmap資源
ic_arrow_down
ic_input_del
icon_del.png
四.layout布局
fragment_pay.xml
支付彈出層布局
<?xml version="1.0" encoding="utf-8"?>
自定義鍵盤布局
<?xml version="1.0" encoding="utf-8"?>
五.color資源
<?xml version="1.0" encoding="utf-8"?>#3F51B5 #303F9F #FF4081 #919191 #EBEBEB #f0eff5 #d5d1d1 #FFFFFF #000000 #212121
六.dimen資源
<?xml version="1.0" encoding="utf-8"?>40sp 18sp 15sp 12sp 10sp 20dp 15dp 10dp 10dp 0.5dp 10dp 10dp 50dp 25dp 2px
七.styles樣式
八.輸入鍵盤view
public class PassWordInputView extends LinearLayout implements View.OnClickListener { private InputReceiver inputReceiver; public PassWordInputView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); LayoutInflater.from(context).inflate(R.layout.view_password_input, this); initView(); } private void initView() { findViewById(R.id.btn_1).setOnClickListener(this); findViewById(R.id.btn_2).setOnClickListener(this); findViewById(R.id.btn_3).setOnClickListener(this); findViewById(R.id.btn_4).setOnClickListener(this); findViewById(R.id.btn_5).setOnClickListener(this); findViewById(R.id.btn_6).setOnClickListener(this); findViewById(R.id.btn_7).setOnClickListener(this); findViewById(R.id.btn_8).setOnClickListener(this); findViewById(R.id.btn_9).setOnClickListener(this); findViewById(R.id.btn_0).setOnClickListener(this); findViewById(R.id.btn_del).setOnClickListener(this); findViewById(R.id.layout_hide).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setVisibility(GONE); } }); } @Override public void onClick(View v) { String num = (String) v.getTag(); this.inputReceiver.receive(num); } /** * 設(shè)置接收器 * * @param receiver */ public void setInputReceiver(InputReceiver receiver) { this.inputReceiver = receiver; } /** * 輸入接收器 */ public interface InputReceiver { void receive(String num); } }
九.密碼框view
public class PayPassWordView extends View { private ArrayListresult;//輸入結(jié)果保存 private int count;//密碼位數(shù) private int size;//默認每一格的大小 private Paint mBorderPaint;//邊界畫筆 private Paint mDotPaint;//掩蓋點的畫筆 private int mBorderColor;//邊界顏色 private int mDotColor;//掩蓋點的顏色 private RectF mRoundRect;//外面的圓角矩形 private int mRoundRadius;//圓角矩形的圓角程度 public PayPassWordView(Context context) { super(context); init(null);//初始化 } private InputCallBack inputCallBack;//輸入完成的回調(diào) private PassWordInputView inputMethodView; //輸入鍵盤 public interface InputCallBack { void onInputFinish(String result); } public PayPassWordView(Context context, AttributeSet attrs) { super(context, attrs); init(attrs); } public PayPassWordView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); } /** * 初始化相關(guān)參數(shù) */ void init(AttributeSet attrs) { final float dp = getResources().getDisplayMetrics().density; this.setFocusable(true); this.setFocusableInTouchMode(true); result = new ArrayList<>(); if (attrs != null) { TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.PayPassWordView); mBorderColor = ta.getColor(R.styleable.PayPassWordView_border_color, Color.LTGRAY); mDotColor = ta.getColor(R.styleable.PayPassWordView_dot_color, Color.BLACK); count = ta.getInt(R.styleable.PayPassWordView_count, 6); ta.recycle(); } else { mBorderColor = Color.LTGRAY; mDotColor = Color.GRAY; count = 6;//默認6位密碼 } size = (int) (dp * 30);//默認30dp一格 //color mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mBorderPaint.setStrokeWidth(3); mBorderPaint.setStyle(Paint.Style.STROKE); mBorderPaint.setColor(mBorderColor); mDotPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mDotPaint.setStrokeWidth(3); mDotPaint.setStyle(Paint.Style.FILL); mDotPaint.setColor(mDotColor); mRoundRect = new RectF(); mRoundRadius = (int) (5 * dp); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int w = measureWidth(widthMeasureSpec); int h = measureHeight(heightMeasureSpec); int wsize = MeasureSpec.getSize(widthMeasureSpec); int hsize = MeasureSpec.getSize(heightMeasureSpec); //寬度沒指定,但高度指定 if (w == -1) { if (h != -1) { w = h * count;//寬度=高*數(shù)量 size = h; } else {//兩個都不知道,默認寬高 w = size * count; h = size; } } else {//寬度已知 if (h == -1) {//高度不知道 h = w / count; size = h; } } setMeasuredDimension(Math.min(w, wsize), Math.min(h, hsize)); } private int measureWidth(int widthMeasureSpec) { //寬度 int wmode = MeasureSpec.getMode(widthMeasureSpec); int wsize = MeasureSpec.getSize(widthMeasureSpec); if (wmode == MeasureSpec.AT_MOST) {//wrap_content return -1; } return wsize; } private int measureHeight(int heightMeasureSpec) { //高度 int hmode = MeasureSpec.getMode(heightMeasureSpec); int hsize = MeasureSpec.getSize(heightMeasureSpec); if (hmode == MeasureSpec.AT_MOST) {//wrap_content return -1; } return hsize; } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) {//點擊控件彈出輸入鍵盤 requestFocus(); inputMethodView.setVisibility(VISIBLE); return true; } return true; } @Override protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); if (gainFocus) { inputMethodView.setVisibility(VISIBLE); } else { inputMethodView.setVisibility(GONE); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); final int width = getWidth() - 2; final int height = getHeight() - 2; //先畫個圓角矩形 mRoundRect.set(0, 0, width, height); canvas.drawRoundRect(mRoundRect, 0, 0, mBorderPaint); //畫分割線 for (int i = 1; i < count; i++) { final int x = i * size; canvas.drawLine(x, 0, x, height, mBorderPaint); } //畫掩蓋點, // 這是前面定義的變量 private ArrayList result;//輸入結(jié)果保存 int dotRadius = size / 8;//圓圈占格子的三分之一 for (int i = 0; i < result.size(); i++) { final float x = (float) (size * (i + 0.5)); final float y = size / 2; canvas.drawCircle(x, y, dotRadius, mDotPaint); } } @Override public boolean onCheckIsTextEditor() { return true; } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;//輸入類型為數(shù)字 outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE; return new MyInputConnection(this, false); } public void setInputCallBack(InputCallBack inputCallBack) { this.inputCallBack = inputCallBack; } public void clearResult() { result.clear(); invalidate(); } private class MyInputConnection extends BaseInputConnection { public MyInputConnection(View targetView, boolean fullEditor) { super(targetView, fullEditor); } @Override public boolean commitText(CharSequence text, int newCursorPosition) { //這里是接受輸入法的文本的,我們只處理數(shù)字,所以什么操作都不做 return super.commitText(text, newCursorPosition); } @Override public boolean deleteSurroundingText(int beforeLength, int afterLength) { //軟鍵盤的刪除鍵 DEL 無法直接監(jiān)聽,自己發(fā)送del事件 if (beforeLength == 1 && afterLength == 0) { return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)) && super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)); } return super.deleteSurroundingText(beforeLength, afterLength); } } /** * 設(shè)置輸入鍵盤view * * @param inputMethodView */ public void setInputMethodView(PassWordInputView inputMethodView) { this.inputMethodView = inputMethodView; this.inputMethodView.setInputReceiver(new PassWordInputView.InputReceiver() { @Override public void receive(String num) { if (num.equals("-1")) { if (!result.isEmpty()) { result.remove(result.size() - 1); invalidate(); } } else { if (result.size() < count) { result.add(num); invalidate(); ensureFinishInput(); } } } }); } /** * 判斷是否輸入完成,輸入完成后調(diào)用callback */ void ensureFinishInput() { if (result.size() == count && inputCallBack != null) {//輸入完成 StringBuffer sb = new StringBuffer(); for (String i : result) { sb.append(i); } inputCallBack.onInputFinish(sb.toString()); } } /** * 獲取輸入文字 * * @return */ public String getInputText() { if (result.size() == count) { StringBuffer sb = new StringBuffer(); for (String i : result) { sb.append(i); } return sb.toString(); } return null; } }
十.支付彈出層
public class PayFragment extends DialogFragment implements View.OnClickListener { public static final String EXTRA_CONTENT = "extra_content"; //提示框內(nèi)容 public static final String EXTRA_CONTENT2 = "extra_content2"; //提示框內(nèi)容 public static final String EXTRA_CONTENT3 = "extra_content3"; //提示框內(nèi)容 private PayPassWordView psw_input; private PayPassWordView.InputCallBack inputCallBack; @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // 使用不帶Theme的構(gòu)造器, 獲得的dialog邊框距離屏幕仍有幾毫米的縫隙。 Dialog dialog = new Dialog(getActivity(), R.style.BottomDialog); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); // 設(shè)置Content前設(shè)定 dialog.setContentView(R.layout.fragment_pay); dialog.setCanceledOnTouchOutside(true); //外部點擊取消 // 設(shè)置寬度為屏寬, 靠近屏幕底部。 final Window window = dialog.getWindow(); window.setWindowAnimations(R.style.AnimBottom); window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); final WindowManager.LayoutParams lp = window.getAttributes(); lp.width = WindowManager.LayoutParams.MATCH_PARENT; // 寬度持平 lp.gravity = Gravity.TOP; window.setAttributes(lp); initView(dialog); return dialog; } private void initView(Dialog dialog) { Bundle bundle = getArguments(); if (bundle != null) { TextView tv_content = (TextView) dialog.findViewById(R.id.tv_content); TextView tv_content2 = (TextView) dialog.findViewById(R.id.tv_content2); TextView tv_content3 = (TextView) dialog.findViewById(R.id.tv_content3); tv_content.setText(bundle.getString(EXTRA_CONTENT)); tv_content2.setText(bundle.getString(EXTRA_CONTENT2)); tv_content3.setText(bundle.getString(EXTRA_CONTENT3)); } psw_input = (PayPassWordView) dialog.findViewById(R.id.payPwdView); PassWordInputView inputMethodView = (PassWordInputView) dialog.findViewById(R.id.inputMethodView); psw_input.setInputMethodView(inputMethodView); psw_input.setInputCallBack(inputCallBack); dialog.findViewById(R.id.iv_close).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.iv_close: dismiss(); break; } } /** * 設(shè)置輸入回調(diào) * * @param inputCallBack */ public void setPaySuccessCallBack(PayPassWordView.InputCallBack inputCallBack) { this.inputCallBack = inputCallBack; } }
十一.邏輯代碼中直接引用
public class MainActivity extends AppCompatActivity implements PayPassWordView.InputCallBack, View.OnClickListener { private PayFragment fragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btn_pay).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_pay: Bundle bundle = new Bundle(); bundle.putString(PayFragment.EXTRA_CONTENT, "提現(xiàn)"); bundle.putString(PayFragment.EXTRA_CONTENT2, "¥" + 1.00); bundle.putString(PayFragment.EXTRA_CONTENT3, "額外扣除0.1手續(xù)費"); fragment = new PayFragment();//創(chuàng)建支付彈出框?qū)嵗? fragment.setArguments(bundle);//傳遞信息 fragment.setPaySuccessCallBack(MainActivity.this);//設(shè)置回調(diào) fragment.show(getSupportFragmentManager(), "Pay"); break; } } @Override public void onInputFinish(String result) { Toast.makeText(this, result, Toast.LENGTH_SHORT).show(); fragment.dismiss();//窗口消失 } }
什么都沒有,只有一個點擊事件而已.
分享結(jié)束,這里面的代碼可是有我造假的成分哦,不過,我就是喜歡將優(yōu)秀的東西集成在一起,謝謝觀看!
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。