Android 自定义四格验证码输入框 自动跳到下一格 输入完成自动提交 可自定义输入格式(只输入英文字母或数字)

核心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

        });




 




    


        

    
    


 

你可能感兴趣的:(Android,自定义View)