微信支付android不弹出支付密码窗口,Android自定义View实现微信支付密码输入框

本文实例为大家分享了Android实现微信支付密码输入框的具体代码,供大家参考,具体内容如下

效果图

0f13986d7454b50137091fd26adc5263.gif

项目中使用到了支付密码功能,其实这类界面是比较常用的,涉及支付密码的输入的一般都会用到对的,所以单独地把这部分抽取出来,有需要的朋友可以拿去用哈!

效果就是支付,弹出密码框,输入密码,这个过程密码不可见,并且提供一个输入完毕的监听!

这个弹出层呢,其实就是一个DialogFragment,逻辑封装在其内部

一.弹出层进出动画 (anim文件)

push_bottom_in.xml

android:duration="200"

android:fromYDelta="100%p"

android:toYDelta="0" />

push_bottom_out.xml

android:duration="200"

android:fromYDelta="0"

android:toYDelta="100%p" />

二.drawable资源

selector_item_pressed.xml

键盘的点击效果

shape_dialog.xml

android:shape="rectangle">

弹出框样式

三.mipmap资源

ic_arrow_down

06578c063b2e014d07b983173dbd8524.png

ic_input_del

e660e56f8012b171067170f622cf9082.png

icon_del.png

879c025a269c5444f61e67154d9f4eb3.png

四.layout布局

fragment_pay.xml

支付弹出层布局

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginLeft="40dp"

android:layout_marginRight="40dp"

android:layout_marginTop="100dp"

android:background="@drawable/shape_dialog"

android:orientation="vertical"

android:paddingBottom="@dimen/spacing_large">

android:layout_width="match_parent"

android:layout_height="wrap_content">

style="@style/style_black_normal_text"

android:layout_width="wrap_content"

android:layout_height="@dimen/text_item_height"

android:layout_centerInParent="true"

android:gravity="center"

android:text="请输入支付密码"

android:textSize="20sp"

android:textStyle="bold" />

android:id="@+id/iv_close"

android:clickable="true"

android:layout_width="28dp"

android:layout_height="28dp"

android:layout_alignParentLeft="true"

android:layout_centerVertical="true"

android:layout_marginLeft="@dimen/spacing_tiny"

android:src="@mipmap/icon_del" />

android:id="@+id/tv_content"

style="@style/style_black_normal_text"

android:layout_width="wrap_content"

android:layout_height="@dimen/text_item_height"

android:layout_gravity="center_horizontal"

android:gravity="center"

android:textStyle="bold" />

android:id="@+id/tv_content2"

style="@style/style_black_money_text"

android:layout_width="wrap_content"

android:layout_height="@dimen/text_item_height"

android:layout_gravity="center_horizontal"

android:gravity="center"

android:textStyle="bold" />

android:id="@+id/tv_content3"

style="@style/style_black_normal_text"

android:layout_width="wrap_content"

android:layout_height="@dimen/text_item_height2"

android:layout_gravity="center_horizontal"

android:gravity="center" />

android:id="@+id/payPwdView"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginLeft="@dimen/spacing_large"

android:layout_marginRight="@dimen/spacing_large"

android:background="@color/white" />

android:id="@+id/inputMethodView"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true" />

自定义键盘布局

android:id="@+id/table_num"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_weight="6"

android:background="@color/gray_line"

android:orientation="vertical">

android:id="@+id/layout_hide"

android:layout_width="match_parent"

android:layout_height="25dp"

android:background="@drawable/selector_item_pressed">

android:layout_width="30dp"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:src="@mipmap/ic_arrow_down" />

android:id="@+id/btn_1"

style="@style/btn_input_num_style"

android:layout_marginRight="@dimen/input_method_spacing"

android:layout_marginTop="@dimen/input_method_spacing"

android:onClick="onClick"

android:tag="1"

android:text="1" />

android:id="@+id/btn_2"

style="@style/btn_input_num_style"

android:layout_marginRight="@dimen/input_method_spacing"

android:layout_marginTop="@dimen/input_method_spacing"

android:tag="2"

android:text="2" />

android:id="@+id/btn_3"

style="@style/btn_input_num_style"

android:layout_marginTop="@dimen/input_method_spacing"

android:tag="3"

android:text="3" />

android:id="@+id/btn_4"

style="@style/btn_input_num_style"

android:layout_marginRight="@dimen/input_method_spacing"

android:tag="4"

android:text="4" />

android:id="@+id/btn_5"

style="@style/btn_input_num_style"

android:layout_marginRight="@dimen/input_method_spacing"

android:tag="5"

android:text="5" />

android:id="@+id/btn_6"

style="@style/btn_input_num_style"

android:tag="6"

android:text="6" />

android:id="@+id/btn_7"

style="@style/btn_input_num_style"

android:layout_marginRight="@dimen/input_method_spacing"

android:tag="7"

android:text="7" />

android:id="@+id/btn_8"

style="@style/btn_input_num_style"

android:layout_marginRight="@dimen/input_method_spacing"

android:tag="8"

android:text="8" />

android:id="@+id/btn_9"

style="@style/btn_input_num_style"

android:tag="9"

android:text="9" />

style="@style/btn_input_num_style"

android:layout_marginRight="@dimen/input_method_spacing"

android:background="@color/gray_btn" />

android:id="@+id/btn_0"

style="@style/btn_input_num_style"

android:layout_marginRight="@dimen/input_method_spacing"

android:tag="0"

android:text="0" />

android:id="@+id/btn_del"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:scaleType="center"

android:src="@mipmap/ic_input_del"

android:tag="-1" />

五.color资源

#3F51B5

#303F9F

#FF4081

#919191

#EBEBEB

#f0eff5

#d5d1d1

#FFFFFF

#000000

#212121

六.dimen资源

40sp

18sp

15sp

12sp

10sp

20dp

15dp

10dp

10dp

0.5dp

10dp

10dp

50dp

25dp

2px

七.styles样式

@color/colorPrimary

@color/colorPrimaryDark

@color/colorAccent

match_parent

wrap_content

true

true

@anim/push_bottom_in

@anim/push_bottom_out

@color/black_text

@dimen/font_normal

false

@color/black_text

@dimen/font_larger

false

match_parent

@dimen/divider_height

@color/gray_line

match_parent

55dp

2px

center

horizontal

0dp

match_parent

1

center

25sp

@color/black_text

@drawable/selector_item_pressed

八.输入键盘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);

}

/**

* 设置接收器

*

* @param receiver

*/

public void setInputReceiver(InputReceiver receiver) {

this.inputReceiver = receiver;

}

/**

* 输入接收器

*/

public interface InputReceiver {

void receive(String num);

}

}

九.密码框view

public class PayPassWordView extends View {

private ArrayList result;//输入结果保存

private int count;//密码位数

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;//输入完成的回调

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);

}

/**

* 初始化相关参数

*/

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;//宽度=高*数量

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;//输入结果保存

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;//输入类型为数字

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) {

//这里是接受输入法的文本的,我们只处理数字,所以什么操作都不做

return super.commitText(text, newCursorPosition);

}

@Override

public boolean deleteSurroundingText(int beforeLength, int afterLength) {

//软键盘的删除键 DEL 无法直接监听,自己发送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);

}

}

/**

* 设置输入键盘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();

}

}

}

});

}

/**

* 判断是否输入完成,输入完成后调用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"; //提示框内容

public static final String EXTRA_CONTENT2 = "extra_content2"; //提示框内容

public static final String EXTRA_CONTENT3 = "extra_content3"; //提示框内容

private PayPassWordView psw_input;

private PayPassWordView.InputCallBack inputCallBack;

@NonNull

@Override

public Dialog onCreateDialog(Bundle savedInstanceState) {

// 使用不带Theme的构造器, 获得的dialog边框距离屏幕仍有几毫米的缝隙。

Dialog dialog = new Dialog(getActivity(), R.style.BottomDialog);

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置Content前设定

dialog.setContentView(R.layout.fragment_pay);

dialog.setCanceledOnTouchOutside(true); //外部点击取消

// 设置宽度为屏宽, 靠近屏幕底部。

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;

}

}

/**

* 设置输入回调

*

* @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, "提现");

bundle.putString(PayFragment.EXTRA_CONTENT2, "¥" + 1.00);

bundle.putString(PayFragment.EXTRA_CONTENT3, "额外扣除0.1手续费");

fragment = new PayFragment();//创建支付弹出框实例

fragment.setArguments(bundle);//传递信息

fragment.setPaySuccessCallBack(MainActivity.this);//设置回调

fragment.show(getSupportFragmentManager(), "Pay");

break;

}

}

@Override

public void onInputFinish(String result) {

Toast.makeText(this, result, Toast.LENGTH_SHORT).show();

fragment.dismiss();//窗口消失

}

}

什么都没有,只有一个点击事件而已.

分享结束,这里面的代码可是有我造假的成分哦,不过,我就是喜欢将优秀的东西集成在一起,谢谢观看!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值