核心View
package cn.deerlands.deerland.mvp.ui.wiget;
import android.app.Activity;
import android.content.Context;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.EditText;
import android.widget.RelativeLayout;
import com.jess.arms.utils.LogUtils;
import java.util.ArrayList;
import java.util.List;
import cn.deerlands.deerland.R;
import cn.deerlands.deerland.mvp.ui.util.KeyBoardUtil;
/**
* 四位验证码View
*/
public class AutoIdentifyView extends RelativeLayout {
EditText identify1;
EditText identify2;
EditText identify3;
EditText identify4;
private String currentCode = "";
public AutoIdentifyView(Context context) {
super(context);
init(context, null);
}
public AutoIdentifyView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
LayoutInflater.from(context).inflate(R.layout.view_auto_identify, this);
identify1 = findViewById(R.id.identify1);
identify2 = findViewById(R.id.identify2);
identify3 = findViewById(R.id.identify3);
identify4 = findViewById(R.id.identify4);
setIdentify();
//让后三个失去焦点,第一个得到焦点
setThirdlyLoseFocusable();
}
/**
* 让后三个失去焦点,第一个得到焦点
*/
private void setThirdlyLoseFocusable() {
loseFocusable(identify1, true);
loseFocusable(identify2, false);
loseFocusable(identify3, false);
loseFocusable(identify4, false);
}
private void loseFocusable(EditText editText, boolean b) {
editText.setFocusable(b);
editText.setFocusableInTouchMode(b);
}
/**
* 设置4个验证码 自动跳到下一个输入框 并且回调第一个和最后一个输入输入完成后的状态 记录输入
*/
private void setIdentify() {
List editTexts = new ArrayList<>();
editTexts.add(identify1);
editTexts.add(identify2);
editTexts.add(identify3);
editTexts.add(identify4);
for (int i = 0; i < editTexts.size(); i++) {
addTextChangeListener(editTexts.get(i), i < editTexts.size() - 1 ?
editTexts.get(i + 1) : null);
}
}
private void addTextChangeListener(EditText currentEdit, EditText nextEdit) {
currentEdit.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
LogUtils.debugInfo("before=" + s.toString());
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
LogUtils.debugInfo("changed=" + s.toString());
}
@Override
public void afterTextChanged(Editable editable) {
String str = editable.toString();
LogUtils.debugInfo(str);
if (currentEdit.getText().toString().length() >= 1) {
currentCode += currentEdit.getText().toString();
if (currentEdit == identify1) { //如果当前是第一输入框,输入完回调
if (firstTextComplete != null) {
firstTextComplete.firstComplete(str);
}
}
//输入完成一个就让其失去焦点
currentEdit.setSelected(true);
loseFocusable(currentEdit, false);
// currentEdit.setFocusable(false);
// currentEdit.setFocusableInTouchMode(false);
if (nextEdit != null) {
nextEdit.setSelected(false);
//获得焦点
loseFocusable(nextEdit, true);
nextEdit.requestFocus();
} else {
//输入完成回调
if (lastTextComplete != null) {
lastTextComplete.lastComplete(currentCode);
}
}
LogUtils.debugInfo("currentCode=" + currentCode);
} else {
// currentCode.replace()
}
}
});
}
/**
* 清除验证码,初始化验证码框状态,弹出键盘
*/
public void initIdentifyBoxKeyboard(Activity activity){
clearContent();
setThirdlyLoseFocusable();
setShowKeyboard(activity);
}
/**
* 弹出键盘
*/
public void setShowKeyboard(Activity activity) {
if (identify1 != null) {
KeyBoardUtil.showInput(identify1, activity);
}
}
public interface LastTextComplete {
void lastComplete(String str);
}
public interface FirstTextComplete {
void firstComplete(String str);
}
LastTextComplete lastTextComplete;
FirstTextComplete firstTextComplete;
/**
* 回调当前的最后一个输入框完成
*/
public void getLastTextComplete(LastTextComplete lastTextComplete) {
this.lastTextComplete = lastTextComplete;
}
/**
* 回调当前的第一个输入框完成
*/
public void getFirsTextComplete(FirstTextComplete firstTextComplete) {
this.firstTextComplete = firstTextComplete;
}
/**
* 设置红色错误状态
*/
public void setErrorStatus() {
//设置红色背景框
setBackResource(identify1, R.drawable.cipher_choose_red);
setBackResource(identify2, R.drawable.cipher_choose_red);
setBackResource(identify3, R.drawable.cipher_choose_red);
setBackResource(identify4, R.drawable.cipher_choose_red);
//清除内容
clearContent();
//第一个获取焦点
loseFocusable(identify1, true);
}
private void clearContent() {
currentCode = "";
identify1.setText("");
identify2.setText("");
identify3.setText("");
identify4.setText("");
}
private void setBackResource(EditText identify, int reId) {
identify.setBackgroundResource(reId);
}
/**
* 初始化状态 加粗字体 不限输入为数字
*/
public void initDeerCipher() {
setBackResource(identify1, R.drawable.cipher_default);
setBackResource(identify2, R.drawable.cipher_default);
setBackResource(identify3, R.drawable.cipher_default);
setBackResource(identify4, R.drawable.cipher_default);
identify1.setInputType(InputType.TYPE_CLASS_TEXT);
identify2.setInputType(InputType.TYPE_CLASS_TEXT);
identify3.setInputType(InputType.TYPE_CLASS_TEXT);
identify4.setInputType(InputType.TYPE_CLASS_TEXT);
}
public String getCurrentCode() {
return currentCode;
}
private void setCurrentCode(String currentCode) {
this.currentCode = currentCode;
}
}
xml文件
KeyBoardUtil
package cn.deerlands.deerland.mvp.ui.util;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import java.util.Timer;
import java.util.TimerTask;
import static android.content.Context.INPUT_METHOD_SERVICE;
public class KeyBoardUtil {
/**
* 显示键盘
*
* @param et 输入焦点
*/
public static void showInput(final EditText et, Activity activity) {
et.setFocusable(true);
et.setFocusableInTouchMode(true);
et.requestFocus();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
InputMethodManager imm =
(InputMethodManager)
activity.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null)
imm.showSoftInput(et, 0);
et.setSelection(et.getText().length());
}
}, 500);
}
/**
* 隐藏键盘
*/
public static void hideInput(Activity activity) {
if (activity.getWindow().getAttributes().softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) {
if (activity.getCurrentFocus() != null) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(INPUT_METHOD_SERVICE);
View v = activity.getWindow().peekDecorView();
if (null != v && imm != null) {
// imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
imm.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
}
public interface OnKeyboardVisibilityListener {
void onVisibilityChanged(boolean visible);
}
/**
* 监听键盘弹出状态
*/
public static void setKeyboardVisibilityListener(Activity activity, final KeyBoardUtil.OnKeyboardVisibilityListener onKeyboardVisibilityListener) {
final View parentView = ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
parentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
private boolean alreadyOpen;
private final int defaultKeyboardHeightDP = 100;
private final int EstimatedKeyboardDP = defaultKeyboardHeightDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);
private final Rect rect = new Rect();
@Override
public void onGlobalLayout() {
int estimatedKeyboardHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, parentView.getResources().getDisplayMetrics());
parentView.getWindowVisibleDisplayFrame(rect);
int heightDiff = parentView.getRootView().getHeight() - (rect.bottom - rect.top);
boolean isShown = heightDiff >= estimatedKeyboardHeight;
if (isShown == alreadyOpen) {
Log.i("Keyboard state", "Ignoring global layout change...");
return;
}
alreadyOpen = isShown;
onKeyboardVisibilityListener.onVisibilityChanged(isShown);
}
});
}
}
使用
//输入完成回调
autoIdentify.getLastTextComplete(str -> {
//输入完成,@ToDo
});