参考http://blog.youkuaiyun.com/a_running_wolf/article/details/50043421 等
公司需求写的仿支付宝支付键盘,在网上找了些代码整理。
当密码输完之后会自动触发一个事件,让你进行一些后续处理。
效果图如下:
说明:
输入密码的键盘是自定义的控件;
本自定义键盘的显示输入密码框部分和键盘部分使分离的,通过CustomKeyBoardUtil将两部分连接起来。这样写的好处是你可以自定义界面的其他部分,对输入键盘没有影响。
自定义键盘控件
首先我们先实现自定义键盘,其布局文件custom_keyboard.xml文件如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#EEEEEE"
android:gravity="bottom">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_custom_keyboard_keys1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text="1"
android:textSize="25sp" />
<TextView
android:id="@+id/tv_custom_keyboard_keys2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text="2"
android:textSize="25sp" />
<TextView
android:id="@+id/tv_custom_keyboard_keys3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text="3"
android:textSize="25sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_custom_keyboard_keys4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text="4"
android:textSize="25sp" />
<TextView
android:id="@+id/tv_custom_keyboard_keys5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text="5"
android:textSize="25sp" />
<TextView
android:id="@+id/tv_custom_keyboard_keys6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text="6"
android:textSize="25sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_custom_keyboard_keys7"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text="7"
android:textSize="25sp" />
<TextView
android:id="@+id/tv_custom_keyboard_keys8"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text="8"
android:textSize="25sp" />
<TextView
android:id="@+id/tv_custom_keyboard_keys9"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text="9"
android:textSize="25sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text=""
android:textSize="25sp" />
<TextView
android:id="@+id/tv_custom_keyboard_keys0"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:text="0"
android:textSize="25sp" />
<ImageView
android:id="@+id/iv_custom_keyboard_keys_delete"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="1px"
android:layout_weight="1"
android:background="@drawable/bg_keyboard_keys"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="10dp"
android:src="@drawable/keyboard_delete"
android:textSize="25sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
在custom_keyboard.xml中需要的数字按钮的背景(按下去会变色),即android:background="@drawable/bg_keyboard_keys"。布局如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false">
<shape>
<solid android:color="#C0C4C7" />
</shape>
</item>
<item android:state_enabled="true" android:state_pressed="false">
<shape>
<solid android:color="@android:color/white" />
</shape>
</item>
<item android:state_enabled="true" android:state_pressed="true">
<shape>
<solid android:color="#C0C4C7" />
</shape>
</item>
</selector>
下面来完成我们自定义键盘控件CustomKeyboardView.java,以及实现键盘控件和输入密码框的关联的帮助类CustomKeyBoardUtil.java。
CustomKeyboardView:
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.hjqjl.testdemo.R;
/**
* 密码输入键盘
*/
public class CustomKeyboardView extends RelativeLayout {
Context context;
private TextView tv0;
private TextView tv1;
private TextView tv2;
private TextView tv3;
private TextView tv4;
private TextView tv5;
private TextView tv6;
private TextView tv7;
private TextView tv8;
private TextView tv9;
private ImageView ivDelete;
public CustomKeyboardView(Context context) {
this(context, null);
}
public CustomKeyboardView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
View view = View.inflate(context, R.layout.custom_keyboard, null);
tv0 = view.findViewById(R.id.tv_custom_keyboard_keys0);
tv1 = view.findViewById(R.id.tv_custom_keyboard_keys1);
tv2 = view.findViewById(R.id.tv_custom_keyboard_keys2);
tv3 = view.findViewById(R.id.tv_custom_keyboard_keys3);
tv4 = view.findViewById(R.id.tv_custom_keyboard_keys4);
tv5 = view.findViewById(R.id.tv_custom_keyboard_keys5);
tv6 = view.findViewById(R.id.tv_custom_keyboard_keys6);
tv7 = view.findViewById(R.id.tv_custom_keyboard_keys7);
tv8 = view.findViewById(R.id.tv_custom_keyboard_keys8);
tv9 = view.findViewById(R.id.tv_custom_keyboard_keys9);
ivDelete = view.findViewById(R.id.iv_custom_keyboard_keys_delete);
addView(view); //必须要,不然不显示控件
}
public TextView getTv0() {
return tv0;
}
public TextView getTv1() {
return tv1;
}
public TextView getTv2() {
return tv2;
}
public TextView getTv3() {
return tv3;
}
public TextView getTv4() {
return tv4;
}
public TextView getTv5() {
return tv5;
}
public TextView getTv6() {
return tv6;
}
public TextView getTv7() {
return tv7;
}
public TextView getTv8() {
return tv8;
}
public TextView getTv9() {
return tv9;
}
public ImageView getIvDelete() {
return ivDelete;
}
}
CustomKeyBoardUtil:
import android.content.Context;
import android.text.method.PasswordTransformationMethod;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
public class CustomKeyBoardUtil {
private Context mContext;
private InputFinishListener mInputOver;
private TextView[] textViews = new TextView[6];
private LinearLayout mLayoutParent;
private CustomKeyboardView mKeyboardView;
/**
* @param layoutParent 传入LinearLayout(密码的父布局,在本类中new的TextView,添加入父布局中的)
* @param keyboardView 传入自定义的键盘
* @param inputOver 回调函数,会得到输入的密码
*/
public CustomKeyBoardUtil(Context context, LinearLayout layoutParent, CustomKeyboardView keyboardView, InputFinishListener inputOver) {
this.mContext = context;
this.mLayoutParent = layoutParent;
this.mInputOver = inputOver;
this.mKeyboardView = keyboardView;
initTextViews();
}
/**
* 初始化输入框,实例化TextView放入到父布局中
* (实现密码输入框)
*/
private void initTextViews() {
for (int i = 0; i < textViews.length; i++) {
textViews[i] = new TextView(mContext);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
params.weight = 1;
textViews[i].setLayoutParams(params);
mLayoutParent.addView(textViews[i]);
textViews[i].setTransformationMethod(PasswordTransformationMethod.getInstance());
textViews[i].setGravity(Gravity.CENTER);
textViews[i].setTextSize(30);
if (i < textViews.length - 1) {
View view = new View(mContext);
LinearLayout.LayoutParams viewParams = new LinearLayout.LayoutParams(1, LinearLayout.LayoutParams.MATCH_PARENT);
view.setLayoutParams(viewParams);
view.setBackgroundColor(ContextCompat.getColor(mContext, android.R.color.holo_red_dark));
mLayoutParent.addView(view);
}
}
setOnKeysListener();
}
/**
* mKeyboardView的点击事件,分别是0123456789和删除键。
*/
private void setOnKeysListener() {
mKeyboardView.getTv0().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inputTextView("0");
}
});
mKeyboardView.getTv1().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inputTextView("1");
}
});
mKeyboardView.getTv2().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inputTextView("2");
}
});
mKeyboardView.getTv3().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inputTextView("3");
}
});
mKeyboardView.getTv4().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inputTextView("4");
}
});
mKeyboardView.getTv5().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inputTextView("5");
}
});
mKeyboardView.getTv6().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inputTextView("6");
}
});
mKeyboardView.getTv7().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inputTextView("7");
}
});
mKeyboardView.getTv8().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inputTextView("8");
}
});
mKeyboardView.getTv9().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inputTextView("9");
}
});
mKeyboardView.getIvDelete().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
deleteTextView();
}
});
}
private View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View view) {
}
};
public void showKeyboard() {
int visibility = mKeyboardView.getVisibility();
if (visibility == View.GONE || visibility == View.INVISIBLE) {
mKeyboardView.setVisibility(View.VISIBLE);
}
}
public void hideKeyboard() {
int visibility = mKeyboardView.getVisibility();
if (visibility == View.VISIBLE) {
mKeyboardView.setVisibility(View.INVISIBLE);
}
}
/**
* 输入密码
*/
private void inputTextView(String code) {
for (int i = 0; i < textViews.length; i++) {
TextView tv = textViews[i];
if (tv.getText().toString().equals("")) {
tv.setText(code);
if (i == textViews.length - 1) {
mInputOver.inputHasOver(getInputText());//当密码输入到最后一个了,回调此方法
}
return;
}
}
}
/**
* 清空所有密码
*/
public void clearTextView() {
for (int i = textViews.length - 1; i >= 0; i--) {
TextView tv = textViews[i];
if (!tv.getText().toString().equals("")) {
tv.setText("");
}
mLayoutParent.invalidate();
}
}
/**
* 删除最后一格的密码
*/
private void deleteTextView() {
for (int i = textViews.length - 1; i >= 0; i--) {
TextView tv = textViews[i];
if (!tv.getText().toString().equals("")) {
tv.setText("");
return;
}
}
}
/**
* 获取输入的密码
*/
private String getInputText() {
StringBuffer sb = new StringBuffer();
for (TextView tv : textViews) {
sb.append(tv.getText().toString());
}
return sb.toString();
}
/**
* 输入监听
*/
public interface InputFinishListener {
void inputHasOver(String text);
}
}
下面看看是怎么使用的:
PayPwdKeyboardActivity:
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.hjqjl.testdemo.R;
public class PayPwdKeyboardActivity extends Activity {
public static void actionStart(Context context) {
Intent intent = new Intent(context, PayPwdKeyboardActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_paypwdkeyboard);
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll_paypwdkeyboard_inputpwd);
CustomKeyboardView customKeyboardView = (CustomKeyboardView) findViewById(R.id.custom_keyboard_view_paypwdkeyboard);
CustomKeyBoardUtil customKeyBoardUtil = new CustomKeyBoardUtil(this, linearLayout, customKeyboardView, new CustomKeyBoardUtil.InputFinishListener() {
@Override
public void inputHasOver(String text) {
Toast.makeText(PayPwdKeyboardActivity.this, "输入完成:" + text, Toast.LENGTH_SHORT).show();
}
});
}
}
activity_paypwdkeyboard.xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#624762">
<LinearLayout
android:id="@+id/ll_paypwdkeyboard_inputpwd"
android:layout_width="match_parent"
android:layout_height="50dip"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:layout_marginTop="131dip"
android:background="@drawable/bg_pwd_input"
android:orientation="horizontal" />
<com.hjqjl.testdemo.paypwdkeyboard.CustomKeyboardView
android:id="@+id/custom_keyboard_view_paypwdkeyboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
</RelativeLayout>
在activity_paypwdkeyboard中需要的密码输入框的背景,即:bg_pwd_input.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffff" />
<!-- 描边 :边框宽度与颜色 -->
<stroke
android:width="1dip"
android:color="@android:color/holo_red_dark" />
<!--圆角-->
<corners android:radius="6px" />
</shape>
ok,至此完毕。
源码:https://gitee.com/hjqjl/WhDemo