欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义密码输入框

程序员文章站 2022-05-29 22:19:34
...

自定义密码输入框

功能:
1.自定义长度,改一个数字就可改变密码输入框长度
2.可使用虚拟键盘输入也可以使用实体键盘输入
3.可以直接在外部界面输入,也可以在弹出的输入界面输入。

1.自定义长度,改一个数字就可改变密码输入框长度

使用设置后再追加的方式。我的做法是用一个自定义布局封装一下。

public class PayPwdLayout extends LinearLayout {
    public PayPwdLayout(Context context) {
        super(context);
    }

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

    public PayPwdLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public PayPwdLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public void setPwdLen(int len){
        if(len <=0){
            return;
        }
        removeAllViews();
        for (int i = 0; i < len; i++) {
            TextView tv = new TextView(getContext());
            tv.setPadding(50, 50, 50, 50);
            tv.setText("");
            tv.setGravity(Gravity.CENTER);
            tv.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_card));
            addView(tv);
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tv.getLayoutParams();
            params.height = LinearLayout.LayoutParams.WRAP_CONTENT;
            params.width = 0;
            params.weight = 1;
            tv.setLayoutParams(params);
        }

        initEditText();
    }

private void initEditText() {
        EditText editText = new EditText(getContext());
        editText.setBackgroundColor(0);
        editText.setInputType(InputType.TYPE_CLASS_NUMBER);
        addView(editText);

        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) editText.getLayoutParams();
        params.height = 1;
        params.width = 1;
        editText.setLayoutParams(params);

        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) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                LinearLayout linear_pwd = (LinearLayout) findViewById(R.id.linear_pwd);
                if (s.length() == linear_pwd.getChildCount()-1) {
                    hideKeyboard();
                    if(mOnCheckPwdListener !=null){
                        mOnCheckPwdListener.check(s.toString());
                    }
                }

                for (int i = 0; i < s.length(); i++) {//●
                    TextView tv = (TextView) linear_pwd.getChildAt(i);
                    tv.setText("●");
                }
                for (int j = s.length(); j < linear_pwd.getChildCount()-1; j++) {
                    TextView tv = (TextView) linear_pwd.getChildAt(j);
                    tv.setText("");
                }
            }
        });
    }
}

布局里面就把此布局设为:

  <com.dyy.yonxin.library2.test.paypwd.PayPwdLayout
        android:id="@+id/linear_pwd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:background="@drawable/bg_card"
        android:orientation="horizontal"/>

然后,在java代码中,使用如下写法:

final int PWD_LEN = 5;//此处设置密码长度
PayPwdLayout layout = (PayPwdLayout)findViewById(R.id.linear_pwd);
layout.setPwdLen(PWD_LEN);

可以看到,自定义布局时有个EditText,但是大小1px*1px,几乎不可见。这里是因为,如果隐藏EditText,则EditText会屏蔽输入事件,文本长度变化不会被监听。我的设计思路是,在EditText进行输入时,同步显示上方密码的个数,实际内容则是根据EditText内容进行获取的。此时,会有两种输入方式,虚拟键盘和实体键盘。

虚拟键盘输入和实体键盘输入

虚拟键盘输入,需要弹出键盘并让EditText获取焦点:

/**
     * 虚拟键盘方式输入
     */
    public void showKeyboardInput(){
        if(getChildCount()>0 && getChildAt(getChildCount()-1) instanceof EditText){
            EditText editText = (EditText) getChildAt(getChildCount()-1);
            editText.requestFocus();
            showKeyboard();
        }
    }

实体键盘要考虑到可能出现的功能,基本功能有:设置文本,追加文本,回退一格,清除全部

/**
     * 实体键盘输入追加
     * @param text
     */
    public void appendText(String text){
        if(getChildCount()>0 && getChildAt(getChildCount()-1) instanceof EditText){
            EditText editText = (EditText) getChildAt(getChildCount()-1);
            String beforeTxt = editText.getText().toString();
            if(beforeTxt.length()+text.length() <= getChildCount()-1)
                editText.setText(editText.getText().toString()+text);
        }
    }

    public void delLastText(){
        if(getChildCount()>0 && getChildAt(getChildCount()-1) instanceof EditText){
            EditText editText = (EditText) getChildAt(getChildCount()-1);
            String beforeText = editText.getText().toString();
            if(beforeText.length()>0)
            editText.setText(beforeText.substring(0,beforeText.length()-1));
        }
    }
    /**
     * 强制设置内容
     * @param text
     */
    public void setText(String text){
        if(getChildCount()>0 && getChildAt(getChildCount()-1) instanceof EditText){
            EditText editText = (EditText) getChildAt(getChildCount()-1);
            editText.setText(text);
        }
    }

    public void clear(){
        if(getChildCount()>0 && getChildAt(getChildCount()-1) instanceof EditText){
            EditText editText = (EditText) getChildAt(getChildCount()-1);
            editText.setText("");
        }
    }

全部用法:
自定义控件:

package com.dyy.yonxin.library2.test.paypwd;

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.dyy.yonxin.library2.test.R;

/**
 * Created by 段钰莹 on 2018/3/30.
 */

public class PayPwdLayout extends LinearLayout {
    public PayPwdLayout(Context context) {
        super(context);
    }

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

    public PayPwdLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public PayPwdLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_card));
    }

    public void setPwdLen(int len){
        if(len <=0){
            return;
        }
        removeAllViews();
        for (int i = 0; i < len; i++) {
            TextView tv = new TextView(getContext());
            tv.setPadding(50, 50, 50, 50);
            tv.setText("");
            tv.setGravity(Gravity.CENTER);
            tv.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_card));
            addView(tv);
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tv.getLayoutParams();
            params.height = LinearLayout.LayoutParams.WRAP_CONTENT;
            params.width = 0;
            params.weight = 1;
            tv.setLayoutParams(params);
        }

        initEditText();
    }

    private void initEditText() {
        EditText editText = new EditText(getContext());
        editText.setBackgroundColor(0);
        editText.setInputType(InputType.TYPE_CLASS_NUMBER);
        addView(editText);

        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) editText.getLayoutParams();
        params.height = 1;
        params.width = 1;
        editText.setLayoutParams(params);

        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) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                LinearLayout linear_pwd = (LinearLayout) findViewById(R.id.linear_pwd);
                if (s.length() == linear_pwd.getChildCount()-1) {
                    hideKeyboard();
                    if(mOnCheckPwdListener !=null){
                        mOnCheckPwdListener.check(s.toString());
                    }
                }

                for (int i = 0; i < s.length(); i++) {//●
                    TextView tv = (TextView) linear_pwd.getChildAt(i);
                    tv.setText("●");
                }
                for (int j = s.length(); j < linear_pwd.getChildCount()-1; j++) {
                    TextView tv = (TextView) linear_pwd.getChildAt(j);
                    tv.setText("");
                }
            }
        });
    }

    /**
     * 虚拟键盘方式输入
     */
    public void showKeyboardInput(){
        if(getChildCount()>0 && getChildAt(getChildCount()-1) instanceof EditText){
            EditText editText = (EditText) getChildAt(getChildCount()-1);
            editText.requestFocus();
            showKeyboard();
        }
    }

    /**
     * 实体键盘输入追加
     * @param text
     */
    public void appendText(String text){
        if(getChildCount()>0 && getChildAt(getChildCount()-1) instanceof EditText){
            EditText editText = (EditText) getChildAt(getChildCount()-1);
            String beforeTxt = editText.getText().toString();
            if(beforeTxt.length()+text.length() <= getChildCount()-1)
                editText.setText(editText.getText().toString()+text);
        }
    }

    public void delLastText(){
        if(getChildCount()>0 && getChildAt(getChildCount()-1) instanceof EditText){
            EditText editText = (EditText) getChildAt(getChildCount()-1);
            String beforeText = editText.getText().toString();
            if(beforeText.length()>0)
            editText.setText(beforeText.substring(0,beforeText.length()-1));
        }
    }
    /**
     * 强制设置内容
     * @param text
     */
    public void setText(String text){
        if(getChildCount()>0 && getChildAt(getChildCount()-1) instanceof EditText){
            EditText editText = (EditText) getChildAt(getChildCount()-1);
            editText.setText(text);
        }
    }

    private void showKeyboard() {
        InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
    }

    public void clear(){
        if(getChildCount()>0 && getChildAt(getChildCount()-1) instanceof EditText){
            EditText editText = (EditText) getChildAt(getChildCount()-1);
            editText.setText("");
        }
    }

    private OnCheckPwdListener mOnCheckPwdListener;
    public void setOnCheckPwdListener(OnCheckPwdListener checkPwdListener){
        mOnCheckPwdListener = checkPwdListener;
    }

    public interface OnCheckPwdListener{
        void check(String pwd);
    }

    protected boolean isSoftShowing() {
        //获取当前屏幕内容的高度
        int screenHeight = getActivity().getWindow().getDecorView().getHeight();
        //获取View可见区域的bottom
        Rect rect = new Rect();
        getActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);

        return screenHeight - rect.bottom != 0;
    }


    private void hideKeyboard() {
        InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null && isSoftShowing()) {
            imm.hideSoftInputFromWindow(getActivity().getWindow().getDecorView().getWindowToken(), 0);
        }
    }

    private Activity getActivity(){
        return (Activity) getContext();
    }
}

调用Activity:

public class PayPwdActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pay_pwd);

        initPwdLen();
        initData();
        initKeyboard();
        addListener();
        initPopupWindow();
    }


    private void initPopupWindow() {
        findViewById(R.id.btn_popup_pwd).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PayMoneyWin win = new PayMoneyWin(PayPwdActivity.this, new PayPwdLayout.OnCheckPwdListener(){

                    @Override
                    public void check(String pwd) {
                        checkPwd(pwd);
                    }
                });
//        设置Popupwindow显示位置(从底部弹出)
                win.show(findViewById(R.id.btn_popup_pwd));
            }
        });

    }

    private void addListener() {
        payPwdLayout.setOnCheckPwdListener(new PayPwdLayout.OnCheckPwdListener() {
            @Override
            public void check(String pwd) {
                checkPwd(pwd);
            }
        });
    }

    private PayPwdLayout payPwdLayout;
    private void initPwdLen() {
        payPwdLayout = (PayPwdLayout) findViewById(R.id.linear_pwd);
        payPwdLayout.setPwdLen(8);
    }

    private void initKeyboard() {
        findViewById(R.id.txt_keyboard_1).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_2).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_3).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_4).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_5).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_6).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_7).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_8).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_9).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_0).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_del).setOnClickListener(this);
        findViewById(R.id.txt_keyboard_clear).setOnClickListener(this);
    }


    private void initData() {
        final Button btn_keyboard = (Button) findViewById(R.id.btn_keyboard);
        btn_keyboard.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //这里的判断为了优化视觉效果,不添加则有可能收起再弹出
                payPwdLayout.clear();
                payPwdLayout.showKeyboardInput();
            }
        });
    }



    private void checkPwd(String inputStr) {
        Toast.makeText(this, "验证密码:" + inputStr, Toast.LENGTH_SHORT).show();
    }

    private void hideKeyboard() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null && isSoftShowing()) {
            imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
        }
    }

    protected boolean isSoftShowing() {
        //获取当前屏幕内容的高度
        int screenHeight = getWindow().getDecorView().getHeight();
        //获取View可见区域的bottom
        Rect rect = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);

        return screenHeight - rect.bottom != 0;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.txt_keyboard_0:
                payPwdLayout.appendText("0");
                break;
            case R.id.txt_keyboard_1:
                payPwdLayout.appendText("1");
                break;
            case R.id.txt_keyboard_2:
                payPwdLayout.appendText("2");
                break;
            case R.id.txt_keyboard_3:
                payPwdLayout.appendText("3");
                break;
            case R.id.txt_keyboard_4:
                payPwdLayout.appendText("4");
                break;
            case R.id.txt_keyboard_5:
                payPwdLayout.appendText("5");
                break;
            case R.id.txt_keyboard_6:
                payPwdLayout.appendText("6");
                break;
            case R.id.txt_keyboard_7:
                payPwdLayout.appendText("7");
                break;
            case R.id.txt_keyboard_8:
                payPwdLayout.appendText("8");
                break;
            case R.id.txt_keyboard_9:
                payPwdLayout.appendText("9");
                break;
            case R.id.txt_keyboard_del:
                payPwdLayout.delLastText();

                break;
            case R.id.txt_keyboard_clear:
                payPwdLayout.clear();
                break;
        }
    }
}

半屏弹出框:

public class PayMoneyWin extends PopupWindow implements View.OnClickListener {

    private Context mContext;

    private View view;

    private TextView btn_cancel;


    public PayMoneyWin(Context mContext, final PayPwdLayout.OnCheckPwdListener listener) {

        this.view = LayoutInflater.from(mContext).inflate(R.layout.popup_pay_pwd, null);
//        btn_take_photo = (Button) view.findViewById(R.id.btn_take_photo);
//        btn_pick_photo = (Button) view.findViewById(R.id.btn_pick_photo);
        initView();
        payPwdLayout.setOnCheckPwdListener(new PayPwdLayout.OnCheckPwdListener() {
            @Override
            public void check(String pwd) {
                if(listener!=null)
                    listener.check(pwd);
                dismiss();
            }
        });
        // 设置按钮监听
//        btn_pick_photo.setOnClickListener(itemsOnClick);
//        btn_take_photo.setOnClickListener(itemsOnClick);

        // 设置外部可点击
        this.setOutsideTouchable(true);
        // mMenuView添加OnTouchListener监听判断获取触屏位置如果在选择框外面则销毁弹出框
        this.view.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event) {

                int height = view.findViewById(R.id.pop_layout).getTop();

                int y = (int) event.getY();
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    if (y < height) {
                        dismiss();
                    }
                }
                return true;
            }
        });


    /* 设置弹出窗口特征 */
        // 设置视图
        this.setContentView(this.view);
        // 设置弹出窗体的宽和高
        this.setHeight(RelativeLayout.LayoutParams.WRAP_CONTENT);
        this.setWidth(RelativeLayout.LayoutParams.MATCH_PARENT);

        // 设置弹出窗体可点击
        this.setFocusable(true);

        // 实例化一个ColorDrawable颜色为半透明
        ColorDrawable dw = new ColorDrawable(0xb0000000);
        // 设置弹出窗体的背景
        this.setBackgroundDrawable(dw);

        // 设置弹出窗体显示时的动画,从底部向上弹出
        this.setAnimationStyle(R.style.take_photo_anim);

        setOnDismissListener(new OnDismissListener() {
            @Override
            public void onDismiss() {
                params = getActivity().getWindow().getAttributes();
                params.alpha=1f;
                getActivity().getWindow().setAttributes(params);
            }
        });

    }

    private void initView() {
        initPwdLen();
        initKeyboard();
    }

    private void initKeyboard() {
        view.findViewById(R.id.txt_keyboard_1).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_2).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_3).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_4).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_5).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_6).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_7).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_8).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_9).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_0).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_del).setOnClickListener(this);
        view.findViewById(R.id.txt_keyboard_clear).setOnClickListener(this);
    }

    private PayPwdLayout payPwdLayout;
    private void initPwdLen() {
        payPwdLayout = (PayPwdLayout) view.findViewById(R.id.linear_pwd);
        payPwdLayout.setPwdLen(6);
    }

    private WindowManager.LayoutParams params;
    public void show(View view){
        showAtLocation(view, Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);
        params =getActivity() .getWindow().getAttributes();
        //当弹出Popupwindow时,背景变半透明
        params.alpha=0.7f;
        getActivity().getWindow().setAttributes(params);
    }

    @Override
    public void dismiss() {
        super.dismiss();

    }

    private Activity getActivity(){
        return (Activity) this.view.getContext();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.txt_keyboard_0:
            case R.id.txt_keyboard_1:
            case R.id.txt_keyboard_2:
            case R.id.txt_keyboard_3:
            case R.id.txt_keyboard_4:
            case R.id.txt_keyboard_5:
            case R.id.txt_keyboard_6:
            case R.id.txt_keyboard_7:
            case R.id.txt_keyboard_8:
            case R.id.txt_keyboard_9:
                TextView txt = (TextView) getActivity().findViewById(v.getId());
                payPwdLayout.appendText(txt.getText().toString());
                break;
            case R.id.txt_keyboard_del:
                payPwdLayout.delLastText();

                break;
            case R.id.txt_keyboard_clear:
                payPwdLayout.clear();
                break;
        }
    }
}

弹出框布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:id="@+id/pop_layout"
    android:background="#ffffff"
    android:layout_height="wrap_content">
    <com.dyy.yonxin.library2.test.paypwd.PayPwdLayout
        android:id="@+id/linear_pwd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:background="@drawable/bg_card"
        android:orientation="horizontal"/>

    <EditText
        android:id="@+id/edit_input"
        android:layout_width="1px"
        android:layout_height="1px"
        android:background="@null"
        android:inputType="number"/>
    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:stretchColumns="*">
        <TableRow
            >
            <TextView
                android:id="@+id/txt_keyboard_1"
                style="@style/txt_btn_function"
                android:text="1"/>

            <TextView
                android:id="@+id/txt_keyboard_2"
                style="@style/txt_btn_function"
                android:text="2"/>
            <TextView
                android:id="@+id/txt_keyboard_3"
                style="@style/txt_btn_function"
                android:text="3"/>
        </TableRow>
        <TableRow
            >
            <TextView
                android:id="@+id/txt_keyboard_4"
                style="@style/txt_btn_function"
                android:text="4"/>

            <TextView
                android:id="@+id/txt_keyboard_5"
                style="@style/txt_btn_function"
                android:text="5"/>
            <TextView
                android:id="@+id/txt_keyboard_6"
                style="@style/txt_btn_function"
                android:text="6"/>
        </TableRow>
        <TableRow
            >
            <TextView
                android:id="@+id/txt_keyboard_7"
                style="@style/txt_btn_function"
                android:text="7"/>

            <TextView
                android:id="@+id/txt_keyboard_8"
                style="@style/txt_btn_function"
                android:text="8"/>
            <TextView
                android:id="@+id/txt_keyboard_9"
                style="@style/txt_btn_function"
                android:text="9"/>
        </TableRow>

        <TableRow
            >
            <TextView
                android:id="@+id/txt_keyboard_clear"
                style="@style/txt_btn_function"
                android:background="@drawable/bg_card2"
                android:text="清空"/>
            <TextView
                android:id="@+id/txt_keyboard_0"
                style="@style/txt_btn_function"
                android:text="0"/>
            <TextView
                android:id="@+id/txt_keyboard_del"
                style="@style/txt_btn_function"
                android:background="@drawable/bg_card2"
                android:text="擦除"/>
        </TableRow>
    </TableLayout>
</LinearLayout>

Activity布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context="com.dyy.yonxin.library2.test.paypwd.PayPwdActivity">
    <com.dyy.yonxin.library2.test.paypwd.PayPwdLayout
        android:id="@+id/linear_pwd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:background="@drawable/bg_card"
        android:orientation="horizontal"/>

   <TableLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:stretchColumns="*">
       <TableRow
           >
           <TextView
               android:id="@+id/txt_keyboard_1"
               style="@style/txt_btn_function"
               android:text="1"/>

           <TextView
               android:id="@+id/txt_keyboard_2"
               style="@style/txt_btn_function"
               android:text="2"/>
           <TextView
               android:id="@+id/txt_keyboard_3"
               style="@style/txt_btn_function"
               android:text="3"/>
       </TableRow>
       <TableRow
           >
           <TextView
               android:id="@+id/txt_keyboard_4"
               style="@style/txt_btn_function"
               android:text="4"/>

           <TextView
               android:id="@+id/txt_keyboard_5"
               style="@style/txt_btn_function"
               android:text="5"/>
           <TextView
               android:id="@+id/txt_keyboard_6"
               style="@style/txt_btn_function"
               android:text="6"/>
       </TableRow>
       <TableRow
           >
           <TextView
               android:id="@+id/txt_keyboard_7"
               style="@style/txt_btn_function"
               android:text="7"/>

           <TextView
               android:id="@+id/txt_keyboard_8"
               style="@style/txt_btn_function"
               android:text="8"/>
           <TextView
               android:id="@+id/txt_keyboard_9"
               style="@style/txt_btn_function"
               android:text="9"/>
       </TableRow>

       <TableRow
           >
           <TextView
               android:id="@+id/txt_keyboard_clear"
               style="@style/txt_btn_function"
               android:background="@drawable/bg_card2"
               android:text="清空"/>
           <TextView
               android:id="@+id/txt_keyboard_0"
               style="@style/txt_btn_function"
               android:text="0"/>
           <TextView
               android:id="@+id/txt_keyboard_del"
               style="@style/txt_btn_function"
               android:background="@drawable/bg_card2"
               android:text="擦除"/>
       </TableRow>
       <Button
           android:id="@+id/btn_keyboard"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:text="弹出键盘"/>

       <Button
           android:id="@+id/btn_popup_pwd"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:text="弹出输入密码"/>
   </TableLayout>
</LinearLayout>

弹出框动画:

<style name="take_photo_anim" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/pop_enter_anim</item>
        <item name="android:windowExitAnimation">@anim/pop_exit_anim</item>
    </style>

pop_enter_anim.xml

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

    <translate
        android:duration="200"
        android:fromYDelta="100%p"
        android:toYDelta="0" />
    <alpha
        android:duration="200"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />
</set>

pop_exit_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromYDelta="0"
        android:toYDelta="50%p" />
    <alpha
        android:duration="200"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
</set>