Bootstrap

android自定义键盘弹窗

样式布局

要在Android中自定义键盘弹窗,先要创建一个新的XML布局文件,用于定义键盘弹窗的外观和布局。例如,创建一个名为key_alert_dialog.xml的文件,并在其中添加所需的按钮和其他UI元素。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/shape_alert_dialog"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="88dp"
            android:orientation="horizontal">

            <TextView
                style="@style/key_board_title"
                android:text="请输入管理员密码" />

        </LinearLayout>

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#BBBBBB" />

        <LinearLayout
            android:paddingTop="20dp"
            android:paddingStart="48dp"
            android:paddingEnd="48dp"
            android:layout_width="fill_parent"
            android:layout_height="84dp"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv_pay1"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:background="@drawable/key_password"
                android:maxLength="1"
                android:inputType="numberPassword"
                android:textSize="32sp" />
            <TextView
                android:layout_marginStart="24dp"
                android:id="@+id/tv_pay2"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:background="@drawable/key_password"
                android:layout_weight="1"
                android:gravity="center"
                android:maxLength="1"
                android:inputType="numberPassword"
                android:textSize="32sp" />

            <TextView
                android:layout_marginStart="24dp"
                android:id="@+id/tv_pay3"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:background="@drawable/key_password"
                android:layout_weight="1"
                android:gravity="center"
                android:maxLength="1"
                android:inputType="numberPassword"
                android:textSize="32sp" />

            <TextView
                android:id="@+id/tv_pay4"
                android:layout_marginStart="24dp"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:background="@drawable/key_password"
                android:layout_weight="1"
                android:gravity="center"
                android:maxLength="1"
                android:inputType="numberPassword"
                android:textSize="32sp" />

            <TextView
                android:id="@+id/tv_pay5"
                android:layout_marginStart="24dp"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:background="@drawable/key_password"
                android:layout_weight="1"
                android:gravity="center"
                android:maxLength="1"
                android:inputType="numberPassword"
                android:textSize="32sp" />

            <TextView
                android:id="@+id/tv_pay6"
                android:layout_marginStart="24dp"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:background="@drawable/key_password"
                android:layout_weight="1"
                android:gravity="center"
                android:maxLength="1"
                android:inputType="numberPassword"
                android:textSize="32sp" />

        </LinearLayout>


        <!--        以下为键盘-->

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="#FFFFFF"
                android:orientation="vertical">

                <LinearLayout
                    android:paddingStart="48dp"
                    android:paddingEnd="48dp"
                    android:layout_width="fill_parent"
                    android:layout_height="71dp"
                    android:orientation="horizontal">

                    <TextView
                        android:id="@+id/num1"
                        style="@style/key_board_text"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="1" />

                    <TextView
                        android:id="@+id/num2"
                        style="@style/key_board_text"
                        android:layout_marginLeft="60dp"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="2" />

                    <TextView
                        android:id="@+id/num3"
                        style="@style/key_board_text"
                        android:layout_marginLeft="60dp"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="3" />
                </LinearLayout>

                <!--  -->

                <LinearLayout
                    android:paddingStart="48dp"
                    android:paddingEnd="48dp"
                    android:layout_width="fill_parent"
                    android:layout_height="71dp"
                    android:layout_marginTop="20dp"
                    android:orientation="horizontal">

                    <TextView
                        android:id="@+id/num4"
                        style="@style/key_board_text"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="4" />

                    <TextView
                        android:id="@+id/num5"
                        style="@style/key_board_text"
                        android:layout_marginLeft="60dp"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="5" />

                    <TextView
                        android:id="@+id/num6"
                        style="@style/key_board_text"
                        android:layout_marginLeft="60dp"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="6" />
                </LinearLayout>

                <!--  -->

                <LinearLayout
                    android:paddingStart="48dp"
                    android:paddingEnd="48dp"
                    android:layout_width="fill_parent"
                    android:layout_height="71dp"
                    android:layout_marginTop="20dp"
                    android:orientation="horizontal">

                    <TextView
                        android:id="@+id/num7"
                        style="@style/key_board_text"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="7" />

                    <TextView
                        android:id="@+id/num8"
                        style="@style/key_board_text"
                        android:layout_marginLeft="60dp"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="8" />

                    <TextView
                        android:id="@+id/num9"
                        style="@style/key_board_text"
                        android:layout_marginLeft="60dp"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="9" />
                </LinearLayout>
                <!--  -->

                <LinearLayout
                    android:paddingStart="48dp"
                    android:paddingEnd="48dp"
                    android:layout_width="fill_parent"
                    android:layout_height="71dp"
                    android:layout_marginTop="20dp"
                    android:orientation="horizontal">

                    <TextView
                        android:id="@+id/num0"
                        style="@style/key_board_text"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="0" />

                    <ImageView
                        android:id="@+id/del"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:layout_width="0dp"
                        android:layout_marginLeft="60dp"
                        android:background="@drawable/shape_key_board_bg"
                        android:src="@drawable/md_backspace" />
                </LinearLayout>


                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:layout_marginTop="20dp"
                    android:background="#BBBBBB" />

                <RelativeLayout
                    android:layout_width="fill_parent"
                    android:layout_height="88dp"
                    android:orientation="horizontal"
                    android:paddingStart="48dp"
                    android:paddingTop="14dp"
                    android:paddingEnd="48dp">


                    <TextView
                        android:id="@+id/cancel"
                        style="@style/key_board_text"
                        android:layout_width="match_parent"
                        android:layout_height="60dp"
                        android:background="@drawable/shape_key_board_bg"
                        android:text="取消" />

                </RelativeLayout>
            </LinearLayout>
        </LinearLayout>


    </LinearLayout>

</LinearLayout>

其中,数字键盘和背景的样式举例如下:

<style name="key_board_text">
        <item name="android:textSize">32sp</item>
        <item name="android:textColor">#333333</item>
        <item name="android:gravity">center</item>
        <item name="android:layout_weight">1</item>
        <item name="android:layout_width">0dp</item>
        <item name="android:textStyle">bold</item>
        <item name="android:layout_height">match_parent</item>
    </style>

    

shape_alert_dialog.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#ffffff"/>

    <corners android:radius="16dp"/>

</shape>

    

密码输入框灰色:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="4dp" />
    <solid android:color="#F5F5F5" />
</shape>

建立一个LinearLayout类为自定义键盘上的每个按钮设置点击事件监听器,以便在用户点击时执行相应的操作。你可以在布局文件中为每个按钮设置android:onClick属性,或者在代码中动态地为它们设置监听器,并设置text的显示,最后定义一个接口(onInputChanged)以便在输入满6位时通知实现者:

public class KeyBoardView extends LinearLayout implements View.OnClickListener {


    View[] numberViews;

    View delView;

    private TextView tvFirst, tvSecond, tvThird, tvForth, tvFifth, tvSixth;


    private StringBuilder mPassword;

    public KeyBoardView(Context context) {
        this(context, null);
    }

    public KeyBoardView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        InitView(context);
    }

    private void InitView(Context context) {
        //绑定0-9
        numberViews = new View[10];
        View view = LayoutInflater.from(context).inflate(R.layout.key_alert_dialog, this);
        Context viewContext = view.getContext();
        for (int i = 0; i < numberViews.length; i++) {
            int id = viewContext.getResources().getIdentifier("num" + i, "id", context.getPackageName());
            numberViews[i] = findViewById(id);
            numberViews[i].setOnClickListener(this);
        }
        //绑定删除
        delView = findViewById(R.id.del);
        delView.setOnClickListener(this);
        initPayEditText(view);

    }

    private void initPayEditText(View view) {
        mPassword = new StringBuilder();
        tvFirst = view.findViewById(R.id.tv_pay1);
        tvSecond = view.findViewById(R.id.tv_pay2);
        tvThird = view.findViewById(R.id.tv_pay3);
        tvForth = view.findViewById(R.id.tv_pay4);
        tvFifth = view.findViewById(R.id.tv_pay5);
        tvSixth = view.findViewById(R.id.tv_pay6);
    }

    @Override
    public void onClick(View view) {
        if (getNumberClicked(view) != -1) {
            add(getNumberClicked(view));
        }

        if (view.getId() == R.id.del) {
            remove();
        }
    }

    /**
     * 删除密码
     */
    public void remove() {
        if (mPassword != null && mPassword.length() > 0) {
            if (mPassword.length() == 1) {
                tvFirst.setText("");
            } else if (mPassword.length() == 2) {
                tvSecond.setText("");
            } else if (mPassword.length() == 3) {
                tvThird.setText("");
            } else if (mPassword.length() == 4) {
                tvForth.setText("");
            } else if (mPassword.length() == 5) {
                tvFifth.setText("");
            } else if (mPassword.length() == 6) {
                tvSixth.setText("");
            }
            mPassword.deleteCharAt(mPassword.length() - 1);
        }
    }


    /**
     * 输入密码
     *
     * @param valueInt
     */
    public void add(int valueInt) {
        String value = Integer.toString(valueInt);
        if (mPassword != null && mPassword.length() < 6) {
            mPassword.append(value);
            if (mPassword.length() == 1) {
                tvFirst.setText(value);
            } else if (mPassword.length() == 2) {
                tvSecond.setText(value);
            } else if (mPassword.length() == 3) {
                tvThird.setText(value);
            } else if (mPassword.length() == 4) {
                tvForth.setText(value);
            } else if (mPassword.length() == 5) {
                tvFifth.setText(value);
            } else if (mPassword.length() == 6) {
                tvSixth.setText(value);
                //业务
                inputCallback.onInputChanged(mPassword.toString());
            }

        }
    }


    public int getNumberClicked(View view) {
        int result = -1;
        for (int i = 0; i < numberViews.length; i++) {
            if (view.equals(numberViews[i])) {
                result = i;
                break;
            }
        }
        return result;
    }



    private InputCallback inputCallback;

    public void setInputListener(InputCallback inputCallback) {
        this.inputCallback = inputCallback;
    }

    public interface InputCallback {

        void onInputChanged(String text);

    }
}

自定义的弹窗

自定义PasswordDialog 继承 Dialog,将自定义布局加载到当前弹窗,并且将我们的取消按钮增加点击事件。最后,我们实现视图KeyBoardView的InputCallback接口完成数据接收:

public class PasswordDialog extends Dialog implements View.OnClickListener{

    private Activity context;

    TextView cancel;
    
    public PasswordDialog(@NonNull Activity context) {
        super(context);
        this.context = context;
        InitView();
    }

    private void InitView() {
        // 设置自定义布局
        KeyBoardView keyBoardView = new KeyBoardView(context);
        setContentView(keyBoardView);
        keyBoardView.setInputListener(text -> {
            if (text.length() == 6) {
                String dPwd = "666666";
                if (!TextUtils.equals(text, dPwd)) {
                    Toast.makeText(context, "密码错误", Toast.LENGTH_SHORT).show();
                } else {
                //校验通过
                    dismiss();
                }
            }
        });

 		cancel = findViewById(R.id.cancel);
        cancel.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
 		if (view.getId() == R.id.cancel) {
            dismiss();
        }
    }
}

调用弹窗中的视图

在你的Activity或Fragment中,使用AlertDialog或其他适当的方法来显示自定义键盘弹窗。首先,加载刚才创建的布局文件,并将其设置为弹窗的内容视图。
在Activity中调用方法,不如在点击事件中调用:

  private PasswordDialog passwordDialog;
      @Override
public void onClick(View view) {
	if (view.getId() == R.id.button) {
            showPasswordDialog(this);
    }
}
       

    /**
     * @param context 上下文对象
     */
    private void showPasswordDialog(Activity context) {
        passwordDialog = new PasswordDialog(context);
        passwordDialog.show();
    }

效果

在这里插入图片描述

;