zoukankan      html  css  js  c++  java
  • 支付宝淘宝

    1.密码输入框

    attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="PasswordEditText">
            <!-- 密码的个数 -->
            <attr name="passwordNumber" format="integer"/>
            <!-- 密码圆点的半径 -->
            <attr name="passwordRadius" format="dimension" />
            <!-- 密码圆点的颜色 -->
            <attr name="passwordColor" format="color" />
            <!-- 分割线的颜色 -->
            <attr name="divisionLineColor" format="color" />
            <!-- 分割线的大小 -->
            <attr name="divisionLineSize" format="color" />
            <!-- 背景边框的颜色 -->
            <attr name="bgColor" format="color" />
            <!-- 背景边框的大小 -->
            <attr name="bgSize" format="dimension" />
            <!-- 背景边框的圆角大小 -->
            <attr name="bgCorner" format="dimension"/>
        </declare-styleable>
    </resources>

    PasswordEditText

    public class PasswordEditText extends EditText {
        // 画笔
        private Paint mPaint;
        // 一个密码所占的宽度
        private int mPasswordItemWidth;
        // 密码的个数默认为6位数
        private int mPasswordNumber = 6;
        // 背景边框颜色
        private int mBgColor = Color.parseColor("#d1d2d6");
        // 背景边框大小
        private int mBgSize = 1;
        // 背景边框圆角大小
        private int mBgCorner = 0;
        // 分割线的颜色
        private int mDivisionLineColor = mBgColor;
        // 分割线的大小
        private int mDivisionLineSize = 1;
        // 密码圆点的颜色
        private int mPasswordColor = mDivisionLineColor;
        // 密码圆点的半径大小
        private int mPasswordRadius = 4;
        private PasswordFullListener mListener;
    
        public PasswordEditText(Context context) {
            this(context, null);
        }
    
        public PasswordEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
            initPaint();
            initAttributeSet(context, attrs);
            // 设置输入模式是密码
            setInputType(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
            // 不显示光标
            setCursorVisible(false);
        }
    
        /**
         * 初始化属性
         */
        private void initAttributeSet(Context context, AttributeSet attrs) {
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.PasswordEditText);
            // 获取大小
            mDivisionLineSize = (int) array.getDimension(R.styleable.PasswordEditText_divisionLineSize, dip2px(mDivisionLineSize));
            mPasswordRadius = (int) array.getDimension(R.styleable.PasswordEditText_passwordRadius, dip2px(mPasswordRadius));
            mBgSize = (int) array.getDimension(R.styleable.PasswordEditText_bgSize, dip2px(mBgSize));
            mBgCorner = (int) array.getDimension(R.styleable.PasswordEditText_bgCorner, 0);
            // 获取颜色
            mBgColor = array.getColor(R.styleable.PasswordEditText_bgColor, mBgColor);
            mDivisionLineColor = array.getColor(R.styleable.PasswordEditText_divisionLineColor, mDivisionLineColor);
            mPasswordColor = array.getColor(R.styleable.PasswordEditText_passwordColor, mDivisionLineColor);
            array.recycle();
        }
    
        /**
         * 初始化画笔
         */
        private void initPaint() {
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
        }
    
        /**
         * dip 转 px
         */
        private int dip2px(int dip) {
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                    dip, getResources().getDisplayMetrics());
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            int passwordWidth = getWidth() - (mPasswordNumber - 1) * mDivisionLineSize;
            mPasswordItemWidth = passwordWidth / mPasswordNumber;
            // 绘制背景
            drawBg(canvas);
            // 绘制分割线
            drawDivisionLine(canvas);
            // 绘制密码
            drawHidePassword(canvas);
        }
    
        /**
         * 绘制背景
         */
        private void drawBg(Canvas canvas) {
            mPaint.setColor(mBgColor);
            // 设置画笔为空心
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBgSize);
            RectF rectF = new RectF(mBgSize, mBgSize, getWidth() - mBgSize, getHeight() - mBgSize);
            // 如果没有设置圆角,就画矩形
            if (mBgCorner == 0) {
                canvas.drawRect(rectF, mPaint);
            } else {
                // 如果有设置圆角就画圆矩形
                canvas.drawRoundRect(rectF, mBgCorner, mBgCorner, mPaint);
            }
        }
    
        /**
         * 绘制隐藏的密码
         */
        private void drawHidePassword(Canvas canvas) {
            int passwordLength = getText().length();
            mPaint.setColor(mPasswordColor);
            // 设置画笔为实心
            mPaint.setStyle(Paint.Style.FILL);
            for (int i = 0; i < passwordLength; i++) {
                int cx = i * mDivisionLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2 + mBgSize;
                canvas.drawCircle(cx, getHeight() / 2, mPasswordRadius, mPaint);
            }
            // 判断密码是否填充完毕
            if (passwordLength >= mPasswordNumber) {
                // 代表密码已经填充满了
                if (mListener != null) {
                    mListener.passwordFull(getText().toString().trim());
                }
            }
        }
    
        /**
         * 绘制分割线
         */
        private void drawDivisionLine(Canvas canvas) {
            mPaint.setStrokeWidth(mDivisionLineSize);
            mPaint.setColor(mDivisionLineColor);
            for (int i = 0; i < mPasswordNumber - 1; i++) {
                int startX = (i + 1) * mDivisionLineSize + (i + 1) * mPasswordItemWidth + mBgSize;
                canvas.drawLine(startX, mBgSize, startX, getHeight() - mBgSize, mPaint);
            }
        }
    
        /**
         * 添加密码
         */
        public void addPassword(String number) {
            number = getText().toString().trim() + number;
            if (number.length() > mPasswordNumber) {
                return;
            }
            setText(number);
        }
    
        /**
         * 删除最后一位密码
         */
        public void deleteLastPassword() {
            String currentText = getText().toString().trim();
            if (TextUtils.isEmpty(currentText)) {
                return;
            }
            currentText = currentText.substring(0, currentText.length() - 1);
            setText(currentText);
        }
    
        /**
         * 设置密码填充满的监听
         */
        public void setOnPasswordFullListener(PasswordFullListener listener) {
            this.mListener = listener;
        }
    
        /**
         * 密码已经全部填满
         */
        public interface PasswordFullListener {
            public void passwordFull(String password);
        }
    }

     目前的效果就是点击之后会弹出系统的键盘,实现了基本的效果,接下来我们再加入监听也就说当密码输入完成我们需要回调监听。 
      
     这里写图片描述

    2.自定义键盘:

    ui_customer_keyboard.xml:

      1 <?xml version="1.0" encoding="utf-8"?>
      2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      3     android:id="@+id/activity_main"
      4     android:layout_width="match_parent"
      5     android:layout_height="wrap_content"
      6     android:background="#EBEBEB"
      7     android:orientation="vertical">
      8 
      9     <LinearLayout
     10         android:layout_width="match_parent"
     11         android:layout_height="wrap_content">
     12 
     13         <TextView
     14             android:layout_width="0dp"
     15             android:layout_height="wrap_content"
     16             android:layout_marginRight="1dp"
     17             android:layout_weight="1"
     18             android:background="#FFFFFF"
     19             android:gravity="center"
     20             android:padding="20dp"
     21             android:text="1" />
     22 
     23         <TextView
     24             android:layout_width="0dp"
     25             android:layout_height="wrap_content"
     26             android:layout_marginRight="1dp"
     27             android:layout_weight="1"
     28             android:background="#FFFFFF"
     29             android:gravity="center"
     30             android:padding="20dp"
     31             android:text="2" />
     32 
     33         <TextView
     34             android:layout_width="0dp"
     35             android:layout_height="wrap_content"
     36             android:layout_weight="1"
     37             android:background="#FFFFFF"
     38             android:gravity="center"
     39             android:padding="20dp"
     40             android:text="3" />
     41     </LinearLayout>
     42 
     43     <LinearLayout
     44         android:layout_width="match_parent"
     45         android:layout_height="wrap_content"
     46         android:layout_marginTop="1dp">
     47 
     48         <TextView
     49             android:layout_width="0dp"
     50             android:layout_height="wrap_content"
     51             android:layout_marginRight="1dp"
     52             android:layout_weight="1"
     53             android:background="#FFFFFF"
     54             android:gravity="center"
     55             android:padding="20dp"
     56             android:text="4" />
     57 
     58         <TextView
     59             android:layout_width="0dp"
     60             android:layout_height="wrap_content"
     61             android:layout_marginRight="1dp"
     62             android:layout_weight="1"
     63             android:background="#FFFFFF"
     64             android:gravity="center"
     65             android:padding="20dp"
     66             android:text="5" />
     67 
     68         <TextView
     69             android:layout_width="0dp"
     70             android:layout_height="wrap_content"
     71             android:layout_weight="1"
     72             android:background="#FFFFFF"
     73             android:gravity="center"
     74             android:padding="20dp"
     75             android:text="6" />
     76     </LinearLayout>
     77 
     78     <LinearLayout
     79         android:layout_width="match_parent"
     80         android:layout_height="wrap_content"
     81         android:layout_marginTop="1dp">
     82 
     83         <TextView
     84             android:layout_width="0dp"
     85             android:layout_height="wrap_content"
     86             android:layout_marginRight="1dp"
     87             android:layout_weight="1"
     88             android:background="#FFFFFF"
     89             android:gravity="center"
     90             android:padding="20dp"
     91             android:text="7" />
     92 
     93         <TextView
     94             android:layout_width="0dp"
     95             android:layout_height="wrap_content"
     96             android:layout_marginRight="1dp"
     97             android:layout_weight="1"
     98             android:background="#FFFFFF"
     99             android:gravity="center"
    100             android:padding="20dp"
    101             android:text="8" />
    102 
    103         <TextView
    104             android:layout_width="0dp"
    105             android:layout_height="wrap_content"
    106             android:layout_weight="1"
    107             android:background="#FFFFFF"
    108             android:gravity="center"
    109             android:padding="20dp"
    110             android:text="9" />
    111 
    112     </LinearLayout>
    113 
    114     <LinearLayout
    115         android:layout_width="match_parent"
    116         android:layout_height="wrap_content"
    117         android:layout_marginTop="1dp"
    118         android:orientation="horizontal">
    119 
    120         <TextView
    121             android:layout_width="0dp"
    122             android:layout_height="wrap_content"
    123             android:layout_marginRight="1dp"
    124             android:layout_weight="1"
    125             android:gravity="center"
    126             android:padding="20dp" />
    127 
    128         <TextView
    129             android:layout_width="0dp"
    130             android:layout_height="wrap_content"
    131             android:layout_marginRight="1dp"
    132             android:layout_weight="1"
    133             android:background="#FFFFFF"
    134             android:gravity="center"
    135             android:padding="20dp"
    136             android:text="0" />
    137 
    138         <ImageView
    139             android:layout_width="0dp"
    140             android:layout_height="wrap_content"
    141             android:layout_weight="1"
    142             android:gravity="center"
    143             android:padding="15dp"
    144             android:layout_gravity="center_vertical"
    145             android:src="@drawable/customer_password_keyboard_delete" />
    146     </LinearLayout>
    147 </LinearLayout>
    View Code

    CustomerKeyboard.java:

     1 public class CustomerKeyboard extends LinearLayout implements View.OnClickListener {
     2     private CustomerKeyboardClickListener mListener;
     3 
     4     public CustomerKeyboard(Context context) {
     5         this(context, null);
     6     }
     7 
     8     public CustomerKeyboard(Context context, AttributeSet attrs) {
     9         this(context, attrs, 0);
    10     }
    11 
    12     public CustomerKeyboard(Context context, AttributeSet attrs, int defStyleAttr) {
    13         super(context, attrs, defStyleAttr);
    14         inflate(context, R.layout.ui_customer_keyboard, this);
    15         setChildViewOnclick(this);
    16     }
    17 
    18     /**
    19      * 设置键盘子View的点击事件
    20      */
    21     private void setChildViewOnclick(ViewGroup parent) {
    22         int childCount = parent.getChildCount();
    23         for (int i = 0; i < childCount; i++) {
    24             // 不断的递归设置点击事件
    25             View view = parent.getChildAt(i);
    26             if (view instanceof ViewGroup) {
    27                 setChildViewOnclick((ViewGroup) view);
    28                 continue;
    29             }
    30             view.setOnClickListener(this);
    31         }
    32     }
    33 
    34     @Override
    35     public void onClick(View v) {
    36         View clickView = v;
    37         if (clickView instanceof TextView) {
    38             // 如果点击的是TextView
    39             String number = ((TextView) clickView).getText().toString();
    40             if (!TextUtils.isEmpty(number)) {
    41                 if (mListener != null) {
    42                     // 回调
    43                     mListener.click(number);
    44                 }
    45             }
    46         } else if (clickView instanceof ImageView) {
    47             // 如果是图片那肯定点击的是删除
    48             if (mListener != null) {
    49                 mListener.delete();
    50             }
    51         }
    52     }
    53 
    54     /**
    55      * 设置键盘的点击回调监听
    56      */
    57     public void setOnCustomerKeyboardClickListener(CustomerKeyboardClickListener listener) {
    58         this.mListener = listener;
    59     }
    60 
    61     /**
    62      * 点击键盘的回调监听
    63      */
    64     public interface CustomerKeyboardClickListener {
    65         public void click(String number);
    66         public void delete();
    67     }
    68 }

    3.最后的测试

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:background="#f7f7f7"
        android:orientation="vertical">
    
        <com.hc.passwordedittext.PasswordEditText
            android:id="@+id/password_edit_text"
            android:layout_width="match_parent"
            android:layout_marginTop="23dp"
            android:layout_marginRight="45dp"
            android:background="@null"
            android:padding="10dp"
            app:bgCorner="3dp"
            android:layout_marginLeft="45dp"
            android:layout_height="wrap_content" />
    
    
        <com.hc.passwordedittext.CustomerKeyboard
            android:id="@+id/custom_key_board"
            android:layout_marginTop="23dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>

    MainActivity.java

     1 public class MainActivity extends Activity implements CustomerKeyboard.CustomerKeyboardClickListener,
     2         PasswordEditText.PasswordFullListener{
     3 
     4     private CustomerKeyboard mCustomerKeyboard;
     5     private PasswordEditText mPasswordEditText;
     6 
     7     @Override
     8     protected void onCreate(Bundle savedInstanceState) {
     9         super.onCreate(savedInstanceState);
    10         setContentView(R.layout.activity_main);
    11         mPasswordEditText = (PasswordEditText) findViewById(R.id.password_et);
    12         mCustomerKeyboard = (CustomerKeyboard) findViewById(R.id.custom_key_board);
    13         // 设置监听
    14         mCustomerKeyboard.setOnCustomerKeyboardClickListener(this);
    15         mPasswordEditText.setOnPasswordFullListener(this);
    16     }
    17 
    18     /**
    19      * 键盘数字点击监听回调方法
    20      */
    21     @Override
    22     public void click(String number) {
    23         mPasswordEditText.addPassword(number);
    24     }
    25 
    26     /**
    27      * 键盘删除点击监听回调方法
    28      */
    29     @Override
    30     public void delete() {
    31         mPasswordEditText.deleteLastPassword();
    32     }
    33 
    34     /**
    35      * 密码输入完毕回调方法
    36      */
    37     @Override
    38     public void passwordFull(String password) {
    39         Toast.makeText(this, "密码填充完毕:" + password, Toast.LENGTH_SHORT).show();
    40     }
    41 }

     这里写图片描述

    https://github.com/HCDarren/PasswordEditText

  • 相关阅读:
    python视频教程大全(转载)
    数据挖掘十大经典算法(转载)
    等值线算法(转载)
    主成分分析PCA(转载)
    K-Means 算法(转载)
    面试常见问题小结
    二叉树的深度和宽度
    二叉树最大路径和-Binary Tree Maximum Path Sum
    C++中单例模式
    OC对象的动态和静态构造区别
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/8144222.html
Copyright © 2011-2022 走看看