可设置自定义键盘布局;
可拦截并自定义按键响应(固定功能按键不可更改);
可设置按键位置随机(仅随机字母和数字)
密码输入框可设置显示与不显示密码
/**
* 创建者:TomCat0916
* 创建时间:2020/4/25
* 功能描述:
* 1、重载样式{@link R.style#PassWordEditText}和{@link R.style#RandomKeyboardDialog}可自定义布局中密码框和软键盘样式
* 2、设置{@link #xml}自定义软键盘布局,通过{@link Builder#setCustomKeyDealListener(OnCustomKeyDealListener)}监听配置自定义键盘操作(出固定功能键shift/delete/enter)
* 3、不改变固有控件id情况下重载{@link R.layout#dialog_keyboard},可实现布局自定义
* 示例
*
* RandomKeyboardDialog.builder()
* .isUseStateView(true)
* .setOnInputCompletedListener((value, callback) -> {
* new Handler().postDelayed(() -> callback.onCheckedResult(true), 3000);
* })
* .create(context)
* .show();
*
*/
public class RandomKeyboardDialog extends BaseDialog implements View.OnClickListener, OnInputCompletedListener, OnCheckResultCallback {
private StateView stateView;
private PasswordEditText etInput;
private RandomKeyboard randomKeyboard;
private OnInputCompletedListener listener;
private OnCustomKeyDealListener keyDealListener;
private @XmlRes
int xml = 0;
private String title;
private int passwordLength;
private boolean isVisible;
private boolean isUseStateView;
@Override
public void destroy() {
if (randomKeyboard!=null){
randomKeyboard.onDestroy();
randomKeyboard = null;
}
etInput = null;
listener = null;
stateView = null;
keyDealListener = null;
super.destroy();
}
private RandomKeyboardDialog(@NonNull Context context, Builder builder) {
super(context, builder);
isUseStateView = builder.isUseStateView;
title = builder.title;
if (builder.listener != null) {
listener = builder.listener;
}
keyDealListener = builder.keyDealListener;
xml = builder.xml;
passwordLength = builder.passwordLength;
isVisible = builder.isVisible;
}
@Override
public void initView(View inflate) {
//禁用系统输入法
if (getWindow() != null) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
ImageView imgDismiss = findViewById(R.id.img_dismiss);
randomKeyboard = findViewById(R.id.random_keyboard);
TextView tvTitle = findViewById(R.id.tv_title);
if (tvTitle != null) {
tvTitle.setText(title);
}
etInput = findViewById(R.id.et_input);
stateView = findViewById(R.id.state_view);
if (randomKeyboard != null && etInput != null) {
etInput.setOnClickListener(this);
etInput.requestFocus();
etInput.setOnInputCompletedListener(this);
etInput.setSelection(etInput.length());
if (passwordLength > 0) {
etInput.setPasswordLength(passwordLength);
}
etInput.setPasswordVisible(isVisible);
try {
context.getResources().getXml(xml);
randomKeyboard.setCustomKeyboard(xml);
} catch (Resources.NotFoundException e) {
e.printStackTrace();
}
randomKeyboard.setOnCustomKeyDealListener(keyDealListener);
randomKeyboard.bindEditText(etInput);
randomKeyboard.isRandom(true);
randomKeyboard.show();
}
if (imgDismiss != null) {
imgDismiss.setOnClickListener(this);
}
}
@Override
public void initData() {
}
public static Builder builder() {
return new Builder();
}
public static class Builder extends BaseDialog.Builder {
private String title;
private OnInputCompletedListener listener;
private boolean isUseStateView = false;
private @XmlRes
int xml = 0;
private OnCustomKeyDealListener keyDealListener;
private int passwordLength;
private boolean isVisible = true;
@Override
public void destroy() {
listener = null;
keyDealListener = null;
}
public Builder setTitle(String title) {
this.title = title;
return this;
}
public Builder setOnInputCompletedListener(OnInputCompletedListener listener) {
this.listener = listener;
return this;
}
public Builder isUseStateView(boolean isUseStateView) {
this.isUseStateView = isUseStateView;
return this;
}
public Builder setKeyboardLayout(@XmlRes int xml) {
this.xml = xml;
return this;
}
public Builder setCustomKeyDealListener(OnCustomKeyDealListener keyDealListener) {
this.keyDealListener = keyDealListener;
return this;
}
public Builder setPasswordLength(int passwordLength) {
this.passwordLength = passwordLength;
return this;
}
public Builder setPasswordVisible(boolean isVisible) {
this.isVisible = isVisible;
return this;
}
public RandomKeyboardDialog create(Context context) {
setGravity(Gravity.BOTTOM);
setHeight(WindowManager.LayoutParams.MATCH_PARENT);
setWith(WindowManager.LayoutParams.MATCH_PARENT);
setLayoutResId(R.layout.dialog_keyboard);
return new RandomKeyboardDialog(context, this);
}
}
public void setOnInputCompletedListener(OnInputCompletedListener listener) {
this.listener = listener;
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.et_input) {
etInput.requestFocus();
etInput.setSelection(etInput.length());
randomKeyboard.show();
} else if (id == R.id.img_dismiss) {
dismiss();
}
}
@Override
public void onComplete(String value, OnCheckResultCallback callback) {
if (listener != null) {
if (isUseStateView && stateView != null) {
stateView.show(StateView.STATE_LOADING);
}
listener.onComplete(value, this);
}
}
@Override
public void onCheckedResult(boolean isDeal) {
if (isUseStateView && stateView != null) {
stateView.hide();
}
if (isDeal) {
dismiss();
}
}
}
BaseDialog :https://blog.csdn.net/TomCat0916/article/details/105769678
RandomKeyboard:https://blog.csdn.net/TomCat0916/article/details/105751838
PasswordEditText :https://blog.csdn.net/TomCat0916/article/details/105759569