1. 程式人生 > >Android自定義View之六位密碼框

Android自定義View之六位密碼框

今天是我第一次寫技術部落格,本人也是小菜鳥一枚,工作不滿一年,部落格內容也比較簡單,對專業知識瞭解不夠深入,寫部落格的原因一來是為了分享,而來也是激勵自己,如果內容有什麼錯誤問題,請大家指教糾正。

今天要講的是六位密碼輸入框。先上程式碼。首先是layout.xml檔案

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="55dip"
    android:gravity="center"
    android:layout_gravity="center"
    android:orientation="horizontal">
    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="fill_parent" >
        <EditText
            android:id="@+id/e1"
            android:layout_width="45dip"
            android:layout_height="fill_parent"
            android:background="@drawable/topayl"
            android:gravity="center"
            android:inputType="numberPassword"
            android:maxLength="1" />
        <TextView
            android:id="@+id/heng1"
            android:layout_width="15dip"
            android:layout_height="2dip"
            android:layout_gravity="center"
            android:background="@color/black"
            android:gravity="center"
            android:visibility="gone" />
    </FrameLayout>

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="fill_parent" >
        <EditText
            android:id="@+id/e2"
            android:layout_width="45dip"
            android:layout_height="fill_parent"
            android:background="@drawable/topaym"
            android:gravity="center"
            android:inputType="numberPassword"
            android:maxLength="1" />
        <TextView
            android:id="@+id/heng2"
            android:layout_width="15dip"
            android:layout_height="2dip"
            android:layout_gravity="center"
            android:background="@color/black"
            android:gravity="center"
            android:visibility="gone" />
    </FrameLayout>

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="fill_parent" >
        <EditText
            android:id="@+id/e3"
            android:layout_width="45dip"
            android:layout_height="fill_parent"
            android:background="@drawable/topaym"
            android:gravity="center"
            android:inputType="numberPassword"
            android:maxLength="1" />
        <TextView
            android:id="@+id/heng3"
            android:layout_width="15dip"
            android:layout_height="2dip"
            android:layout_gravity="center"
            android:background="@color/black"
            android:gravity="center"
            android:visibility="gone" />
    </FrameLayout>

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="fill_parent" >
        <EditText
            android:id="@+id/e4"
            android:layout_width="45dip"
            android:layout_height="fill_parent"
            android:background="@drawable/topaym"
            android:gravity="center"
            android:inputType="numberPassword"
            android:maxLength="1" />
        <TextView
            android:id="@+id/heng4"
            android:layout_width="15dip"
            android:layout_height="2dip"
            android:layout_gravity="center"
            android:background="@color/black"
            android:gravity="center"
            android:visibility="gone" />
    </FrameLayout>

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="fill_parent" >
        <EditText
            android:id="@+id/e5"
            android:layout_width="45dip"
            android:layout_height="fill_parent"
            android:background="@drawable/topaym"
            android:gravity="center"
            android:inputType="numberPassword"
            android:maxLength="1" />
        <TextView
            android:id="@+id/heng5"
            android:layout_width="15dip"
            android:layout_height="2dip"
            android:layout_gravity="center"
            android:background="@color/black"
            android:gravity="center"
            android:visibility="gone" />
    </FrameLayout>

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="fill_parent" >
        <EditText
            android:id="@+id/e6"
            android:layout_width="45dip"
            android:layout_height="fill_parent"
            android:background="@drawable/topayr"
            android:gravity="center"
            android:inputType="numberPassword"
            android:maxLength="1" />
        <TextView
            android:id="@+id/heng6"
            android:layout_width="15dip"
            android:layout_height="2dip"
            android:layout_gravity="center"
            android:background="@color/black"
            android:gravity="center"
            android:visibility="gone" />
    </FrameLayout>
</LinearLayout>
以上程式碼比較簡單,這裡六個EditText下面的TextView暫時不看。出來的效果是六個框框。

下面是自定義View的程式碼

/**


 * Created by HYQ on 2016/3/3.
 */
public class SixPwdView extends LinearLayout{
    private Context context;
    private SixPwdListener listener;
    private EditText e1,e2,e3,e4,e5,e6;
    private String s_e1, s_e2, s_e3, s_e4, s_e5, s_e6;
    private onKeyListeners onkeylistener;


    public SixPwdView(Context context) {
        super(context);
        this.context = context;
    }


    public SixPwdView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        initView();
    }


    public void clear_edit() {
        e1.setText("");
        e2.setText("");
        e3.setText("");
        e4.setText("");
        e5.setText("");
        e6.setText("");
    }
    /**
     * 取消e6的焦點
     */
    public void clearLastFouse(){
        e6.setFocusable(false);
        e6.setFocusableInTouchMode(false);
        e6.clearFocus();
    }


    public void getLastFouse(){
        e6.setFocusable(true);
        e6.setFocusableInTouchMode(true);
        e6.requestFocus();
        e6.findFocus();
    }


    //初始化view
    private void initView() {
        View view = LayoutInflater.from(context).inflate(R.layout.six_pwd_layout,this);
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);
        params.height = (int) context.getResources().getDimension(R.dimen.dp52);
        view.setLayoutParams(params);
        e1 = (EditText)view.findViewById(R.id.e1);
        e2 = (EditText)view.findViewById(R.id.e2);
        e3 = (EditText)view.findViewById(R.id.e3);
        e4 = (EditText)view.findViewById(R.id.e4);
        e5 = (EditText)view.findViewById(R.id.e5);
        e6 = (EditText)view.findViewById(R.id.e6);
        onkeylistener = new onKeyListeners();
        e1.setOnKeyListener(onkeylistener);
        e2.setOnKeyListener(onkeylistener);
        e3.setOnKeyListener(onkeylistener);
        e4.setOnKeyListener(onkeylistener);
        e5.setOnKeyListener(onkeylistener);
        e6.setOnKeyListener(onkeylistener);


        e1.setCursorVisible(false);
        e2.setCursorVisible(false);
        e3.setCursorVisible(false);
        e4.setCursorVisible(false);
        e5.setCursorVisible(false);
        e6.setCursorVisible(false);
        clear_focuse();
        setaddTextChangedListener();
    }


    private  void setaddTextChangedListener(){
        e1.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) {
                if (e1.getText().toString().equals("")) {
                    // heng1.setVisibility(View.VISIBLE);
                } else {
                    s_e1 = e1.getText().toString();
                    e2_focuse();
                }
            }
        });


        e2.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) {
                if (e2.getText().toString().equals("")) {
                } else {
                    s_e2 = e2.getText().toString();
                    e3_focuse();
                }
            }
        });


        e3.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) {
                if (e3.getText().toString().equals("")) {
                } else {
                    s_e3 = e3.getText().toString();
                    e4_focuse();
                }
            }
        });


        e4.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) {
                if (e4.getText().toString().equals("")) {
                } else {
                    s_e4 = e4.getText().toString();
                    e5_focuse();
                }
            }
        });


        e5.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) {
                if (e5.getText().toString().equals("")) {
                } else {
                    s_e5 = e5.getText().toString();
                    last_focuse();
                }
            }
        });


        e6.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) {
                if (e6.getText().toString().equals("")) {
                } else {
                    e6.setFocusable(false);
                    s_e6 = e6.getText().toString();
                    isfirstallwrite();
                }
            }
        });
    }
    public void setLastFocuse(){
        e6.setFocusable(true);
        e6.setFocusableInTouchMode(true);
        e6.requestFocus();
        e6.findFocus();
    }


    public void  getLockTime(){
        e1.setFocusable(false);
        e2.setFocusable(false);
        e3.setFocusable(false);
        e4.setFocusable(false);
        e5.setFocusable(false);
        e6.setFocusable(false);
    }


    String eString = "";
    private void isfirstallwrite() {
        if (!TextUtils.isEmpty(s_e1) && !TextUtils.isEmpty(s_e2) && !TextUtils.isEmpty(s_e3) && !TextUtils.isEmpty(s_e4)
                && !TextUtils.isEmpty(s_e5) && !TextUtils.isEmpty(s_e6)) {
           //getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
            eString = s_e1 + s_e2 + s_e3 + s_e4 + s_e5 + s_e6;
            if (listener != null) {
                listener.onInputComplete(eString);
            }
        }
    }

    /**
     * 點選刪除按鈕監聽
     *
     * @author
     *
     */
    class onKeyListeners implements android.view.View.OnKeyListener {


        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_DEL) {
                if (event.getAction() != KeyEvent.ACTION_UP) {
                    return true;
                }
                if (e6.isFocused()) {
                    if (!TextUtils.isEmpty(e6.getText())) {
                        e6.setText("");
                    } else {
                        e6.clearFocus();
                        e5_focuse();
                        e5.setText("");
                    }
                } else if (e5.isFocused()) {
                    if (!TextUtils.isEmpty(e5.getText())) {
                        e5.setText("");
                    } else {
                        e5.clearFocus();
                        e4_focuse();
                        e4.setText("");
                    }
                } else if (e4.isFocused()) {
                    if (!TextUtils.isEmpty(e4.getText())) {
                        e4.setText("");
                    } else {
                        e4.clearFocus();
                        e3_focuse();
                        e3.setText("");
                    }
                } else if (e3.isFocused()) {
                    if (!TextUtils.isEmpty(e3.getText())) {
                        e3.setText("");
                    } else {
                        e3.clearFocus();
                        e2_focuse();
                        e2.setText("");
                    }
                } else if (e2.isFocused()) {
                    if (!TextUtils.isEmpty(e2.getText())) {
                        e2.setText("");
                    } else {
                        e2.clearFocus();
                        clear_focuse();
                        e1.setText("");
                    }
                }
                return true;
            }
            return false;
        }
    }


    private void e2_focuse() {
        e2.setFocusable(true);
        e2.setFocusableInTouchMode(true);
        e2.requestFocus();
        e2.findFocus();

        e1.setFocusable(false);
        e3.setFocusable(false);
        e4.setFocusable(false);
        e5.setFocusable(false);
        e6.setFocusable(false);
    }


    public void clear_focuse() {
        e1.setFocusable(true);
        e1.setFocusableInTouchMode(true);
        e1.requestFocus();
        e1.findFocus();

        InputMethodManager inputManager = (InputMethodManager) e1.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.showSoftInput(e1, 0);

        e2.setFocusable(false);
        e3.setFocusable(false);
        e4.setFocusable(false);
        e5.setFocusable(false);
        e6.setFocusable(false);
    }


    private void e3_focuse() {
        e3.setFocusable(true);
        e3.setFocusableInTouchMode(true);
        e3.requestFocus();
        e3.findFocus();

        e2.setFocusable(false);
        e1.setFocusable(false);
        e4.setFocusable(false);
        e5.setFocusable(false);
        e6.setFocusable(false);
    }


    private void e4_focuse() {
        e4.setFocusable(true);
        e4.setFocusableInTouchMode(true);
        e4.requestFocus();
        e4.findFocus();

        e2.setFocusable(false);
        e3.setFocusable(false);
        e1.setFocusable(false);
        e5.setFocusable(false);
        e6.setFocusable(false);
    }


    private void e5_focuse() {
        e5.setFocusable(true);
        e5.setFocusableInTouchMode(true);
        e5.requestFocus();
        e5.findFocus();


        e2.setFocusable(false);
        e3.setFocusable(false);
        e4.setFocusable(false);
        e1.setFocusable(false);
        e6.setFocusable(false);
    }


    public void last_focuse() {
        e6.setFocusable(true);
        e6.setFocusableInTouchMode(true);
        e6.requestFocus();
        e6.findFocus();

        e2.setFocusable(false);
        e3.setFocusable(false);
        e4.setFocusable(false);
        e5.setFocusable(false);
        e1.setFocusable(false);
    }

    public void setListener(SixPwdListener listener) {
        this.listener = listener;
    }
    public interface SixPwdListener{
        void onInputComplete(String passWord);
    }
}

很顯然,在這個View裡,首先setaddTextChangedListener()這個方法控制view的焦點,當e1中有資料值,立馬剝奪焦點讓給e2,當e2有資料值時,立馬剝奪焦點讓給e3,如此層層遞進,直到e6,當e6有資料時,通過isfirstallwrite()這個方法收集到6個EditText裡的值,也就是6位密碼,然後通過介面SixPwdListener傳出去,至於要對六位密碼做什麼處理,可以自行定義。這裡要注意的是,當e6獲取到值時,我這裡做的處理是直接把e6的焦點設定為false,即e6.setFocusable(false),這裡有一個問題,我這裡自定義六位密碼框,在前五個EditText時,按軟鍵盤的刪除鍵框內的資料是可以清楚的,只有當e6輸入完成時不可以清楚,應為我的需求是輸入到第六位完成後直接有跳轉處理,所以當碰到輸入完六位密碼想刪除更改時,也就是在 e6.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) {
                if (e6.getText().toString().equals("")) {
                } else {
                    e6.setFocusable(false);
                    s_e6 = e6.getText().toString();
                    isfirstallwrite();
                }
            }
        });
    }
這裡afterTextChanged(Editable s) 裡,各位可以使得e6有焦點,改成
                  @Override
            public void afterTextChanged(Editable s) {
                if (e6.getText().toString().equals("")) {
                } else {
                    e6.setFocusable(false);
                    s_e6 = e6.getText().toString();
                    setLastFocuse();
                    isfirstallwrite();                }            }
其中的setLastFocuse()方法如下:
public void setLastFocuse(){
        e6.setFocusable(true);
        e6.setFocusableInTouchMode(true);
        e6.requestFocus();
        e6.findFocus();
    }
其實這個自定義View總體來說比較簡單,有點基礎的一看就懂,這裡還要說的是,如果在editText輸入完資料後,不剝奪焦點的話,他會有一段過度時間才會讓數字變成圓點。剝奪的焦點的話會立馬變,所以在e6處先剝奪焦點後在設定setFocusable為true.不知道我這麼說大家聽得懂不。。。嗚嗚嗚,文筆不好咩.