ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android 验证码输入框效果实现 焦点自动后移

2021-08-03 19:05:07  阅读:184  来源: 互联网

标签:int editText 验证码 输入框 import input Android public android


来吧 先看效果
需求是输入一位后 将其设置为
也就是加密展示,并将焦点自动转移到下一个框中 当输入至最后一个框时 执行一定逻辑
*

原理: 我们写一个recyclerView 并在recyclerView上面放一个EditText ,这里要注意: 要让EditText覆盖recyclerView ,当我们进行输入时 ,时刻监听EditText内容变化, 一有变化时 ,将当前输入的字符设置给recyclerView的适配器 , 刷新就好
在此 我将这个逻辑代码写成了自定义属性格式 ,扩展性比较高, 使用的话也是非常简单 ,一起来看下吧!
在这里插入图片描述

package com.example.text_1.utils;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.DigitsKeyListener;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.GridLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.text_1.R;
import java.util.ArrayList;
import java.util.List;

public class CustomEditText extends FrameLayout {
    /**
     * 输入是否明文显示
     */
    private boolean showEncryptionText;
    /**
     * 框数量
     */
    private int num;
    /**
     * 当前输入的是否加粗边框
     */
    private boolean sel_show_frame;
    /**
     * 输入至最后一个元素时是否执行跳转等行为
     */
    private boolean input_ok_jump;
    /**
     * 框的背景图  长度为2   0为默认  1为选中
     */
    private List<Integer> input_back = new ArrayList<>();
    /**
     * 监听输入到末尾时的监听
     */
    public endJumpCLick endJumpCLick;
    /**
     * 框的样式(不设置就使用默认样式)
     */
    private int input_adapter_layout = R.layout.input_adapter_layout;
    /**
     * 框的内容集合
     */
    private List<InputBean> textList = new ArrayList<>();
    /**
     * 框适配器
     */
    private InputAdapter inputAdapter = new InputAdapter(textList);

    public void setEndJumpCLick(CustomEditText.endJumpCLick endJumpCLick) {
        this.endJumpCLick = endJumpCLick;
    }

    public CustomEditText(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CustomEditText);
        showEncryptionText = typedArray.getBoolean(R.styleable.CustomEditText_ce_show_encryption_Text, true);
        num = typedArray.getInteger(R.styleable.CustomEditText_ce_Num, 6);
        sel_show_frame = typedArray.getBoolean(R.styleable.CustomEditText_ce_sel_show_frame, true);
        input_ok_jump = typedArray.getBoolean(R.styleable.CustomEditText_ce_input_ok_jump, true);
        typedArray.recycle();

        LayoutParams params = new LayoutParams(GridLayout.LayoutParams.MATCH_PARENT, GridLayout.LayoutParams.MATCH_PARENT);
        RecyclerView recyclerView = new RecyclerView(getContext());
        recyclerView.setLayoutParams(params);
        addView(recyclerView);
        EditText editText = new EditText(getContext());
        editText.setBackground(null);
        editText.setMaxLines(num);
        editText.setCursorVisible(false);
        editText.setKeyListener(new DigitsKeyListener(false, false));
        editText.setTextColor(Color.WHITE);
        editText.setTextSize(1);
        editText.setLayoutParams(params);
        addView(editText);
        initAdapter(recyclerView);
        et_custom_editTextListener(editText);
    }

    private void et_custom_editTextListener(EditText et_custom_editText) {
        et_custom_editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                for (int i = 0; i < textList.size(); i++) {
                    textList.get(i).text = i < s.length() ? showEncryptionText ? String.valueOf(s.charAt(i)) : "*" : "";
                    textList.get(i).isSelect = false;
                }
                if (s.length() < num) textList.get(s.length()).isSelect = true;
                if (input_ok_jump && s.length() == num && endJumpCLick != null) {
                    endJumpCLick.onJumpClick(s.toString());
                }
                inputAdapter.notifyDataSetChanged();
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }

    private void initAdapter(RecyclerView rv_custom_editText) {
        textList.clear();
        for (int i = 0; i < num; i++) textList.add(new InputBean("", i == 0 ? true : false));
        rv_custom_editText.setLayoutManager(new GridLayoutManager(getContext(), textList.size()));
        rv_custom_editText.setAdapter(inputAdapter);
        inputAdapter.notifyDataSetChanged();
    }

    public CustomEditText setInput_backList(List<Integer> data) {
        if (sel_show_frame) {
            if (data.size() == 2) {
                input_back.clear();
                input_back.add(data.get(0));
                input_back.add(data.get(1));
            } else {
                Toast.makeText(getContext(), "数量不符, 添加失败!", Toast.LENGTH_SHORT).show();
            }
        }
        return this;
    }

    public CustomEditText setInputAdapterLayout(int layoutId) {
        input_adapter_layout = layoutId;
        return this;
    }

    class InputBean {
        public String text;
        public boolean isSelect;

        public InputBean(String text, boolean isSelect) {
            this.text = text;
            this.isSelect = isSelect;
        }
    }

    class InputAdapter extends RecyclerView.Adapter {
        public List<InputBean> list;

        public InputAdapter(List<InputBean> list) {
            this.list = list;
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(input_adapter_layout, parent, false));
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            ViewHolder holder1 = (ViewHolder) holder;
            if (sel_show_frame && input_back.size() == 2) {
                holder1.textView.setBackgroundResource(list.get(position).isSelect ? input_back.get(0) : input_back.get(1));
            }
            holder1.textView.setText(list.get(position).text);
        }

        @Override
        public int getItemCount() {
            return list.size();
        }

        class ViewHolder extends RecyclerView.ViewHolder {
            public TextView textView;

            public ViewHolder(View itemView) {
                super(itemView);
                textView = itemView.findViewById(R.id.itemEdit);
            }
        }
    }

    public interface endJumpCLick {
        void onJumpClick(String s);
    }
}

属性如下:

  <declare-styleable name="CustomEditText">
  		//输入是否明文显示
        <attr name="ce_show_encryption_Text" format="boolean" />
        //框的数量
        <attr name="ce_Num" format="integer" />
        //当前输入的框是否有加粗效果
        <attr name="ce_sel_show_frame" format="boolean" />
        //当输入至最后一位时 ,是否执行逻辑  比如调接口等等
        <attr name="ce_input_ok_jump" format="boolean" />
    </declare-styleable>

框的背景样式布局 默认为此样式布局 如果需要更改 则替换布局即可

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="60dp">

    <TextView
        android:id="@+id/itemEdit"
        android:layout_width="50dp"
        android:layout_height="match_parent"
        android:background="@drawable/input_default_back_view"
        android:gravity="center"
        android:textColor="#000000"
        android:textSize="24sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

具体用法: 在activity中:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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"
    tools:context=".DemoActivity">

    <com.example.text_1.utils.CustomEditText
        android:id="@+id/ce_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:ce_sel_show_frame="false"
        app:ce_Num="4"
        app:ce_show_encryption_Text="true"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

此外如果设置了加粗边框 则需要在代码中动态设置背景样式 以数组格式进行设置 下标0为当前存在焦点的样式 1为失去焦点的样式 不可以多传或少传 数组长度只能为2
加粗边框/不加粗xml如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke
        android:width="2dp"
        android:color="@color/black_tran30" />
    <corners android:radius="3dp" />
</shape>


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke
        android:width="0.5dp"
        android:color="#A3A3A3" />
    <corners android:radius="3dp" />
</shape>
package com.example.text_1;

import com.example.text_1.utils.BaseActivity;
import com.example.text_1.utils.CustomEditText;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;

public class DemoActivity extends BaseActivity {
    @BindView(R.id.ce_input)
    CustomEditText ceInput;

    @Override
    public void initView() {
        ceInput.setInput_backList(inputListData());
        ceInput.setEndJumpCLick(s -> showToast(s));
    }

    /**
     * 背景框
     *
     * @return 返回集合
     */
    private List<Integer> inputListData() {
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(R.drawable.edit_shape_focus);
        integers.add(R.drawable.edit_shape_not_focus);
        return integers;
    }

    @Override
    public int getLayout() {
        return R.layout.activity_demo;
    }
}

最终 效果如下:
在这里插入图片描述
希望对你有所帮助

标签:int,editText,验证码,输入框,import,input,Android,public,android
来源: https://blog.csdn.net/weixin_52820423/article/details/119254262

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有