1. 程式人生 > >自定義虛線格式的EditText輸入框

自定義虛線格式的EditText輸入框

好久沒有寫部落格,是覺得沒有太多的東西可寫,今天分享一下,自定義edittext的輸入框,效果圖如下:

  

 這個效果是一個輸入11位手機號的效果圖,分為兩個步驟實現:

  1.畫出虛線,確定寬度和高度

  2.控制焦點的定位。

  虛線並不是一個圖片,而是繼承了EditText後,畫出來的,具體的程式碼如下:

public class VisitCodeEditText extends EditText {
    private Paint paint;
    private Paint textPaint;

    private int perDashWidth;
    private int 
perGapWidth; public VisitCodeEditText(Context context) { super(context); init(context); } public VisitCodeEditText(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public VisitCodeEditText(Context context, AttributeSet attrs, int
defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { paint = new Paint(); paint.setStrokeWidth(2); paint.setStyle(Paint.Style.STROKE); paint.setColor(Color.parseColor("#7386e6")); textPaint
= new Paint(); //設定字型大小 textPaint.setTextSize(Util.dip2px(context,24)); //設定字型型別 textPaint.setTypeface(Typeface.DEFAULT); textPaint.setColor(getResources().getColor(R.color.input_visit_text_color)); //每一個虛線的寬度,1只是代表一個字元佔的寬度,用什麼字元都可以 perDashWidth = (int) getTextLength("1"); //每兩個虛線之間的空格的寬度 perGapWidth = (int) getTextLength(" "); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int specMode = MeasureSpec.getMode(widthMeasureSpec); //計算寬高,設定 int width = perDashWidth * 11 + perGapWidth * 10 + 20; if (specMode == MeasureSpec.EXACTLY || specMode == MeasureSpec.AT_MOST) { setMeasuredDimension(width, Util.dip2px(getContext(), 40)); } } @Override protected void onDraw(Canvas canvas) { int start = 10; for (int i = 0; i < 11; i++) { //畫出每一個虛線 canvas.drawLine(start, getHeight() - 5, start + perDashWidth, getHeight() - 5, paint); start += perDashWidth + perGapWidth; } //必須在此方法之前畫,否則將被覆蓋掉 super.onDraw(canvas); } //獲取文字的寬度 private float getTextLength(String text) { // 使用panit獲取文字的寬度 float textLength = textPaint.measureText(text); return textLength; } }
這裡面的程式碼比較完整,不在過多介紹。
 接下來就是控制焦點定位的過程,因為在繪製的樣式過程中,沒兩個虛線之間加入了一個空格,那麼當你輸入完字元後,焦點會顯示空格處,不會是下一個要輸入的字元處,這就比較尷尬了,而且也非常不方便,需要做一下處理,主要就是使用Edittext的setSelection(int index)這個方法對焦點進行定位。
 定位這個事情是在TextWatcher中實現的,如下:
public class InputVisitCodeTextWatcher implements TextWatcher {

    private EditText mEditText;
    //是否按了回退鍵
private boolean keyDel;
    //臨時字串變數
private String tempStr;

    public static final String CH = "  ";

    public InputVisitCodeTextWatcher(EditText mEditText) {
        this.mEditText = mEditText;
    }

    @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
        String str = s.toString();
        if (tempStr != null && tempStr.length() > str.length()) {
            keyDel = true;
        } else {
            keyDel = false;
        }
        if (!keyDel) {
            if (str.length() == 1) {
                setCustomSelection(s + CH);
                return;
            } else if (str.length() == 2) {
                //按回退鍵後,再次輸入字元
setCustomSelection(str.substring(0, 1) + CH + str.substring(1));
                return;
            } else if (str.length() == 4) {
                setCustomSelection(s + CH);
                return;
            } else if (str.length() == 5) {
                //按回退鍵後,再次輸入字元
setCustomSelection(str.substring(0, 4) + CH + str.substring(4));
                return;
            } else if (str.length() == 7) {
                setCustomSelection(s + CH);
            } else if (str.length() == 8) {
                //按回退鍵後,再次輸入字元
setCustomSelection(str.substring(0, 7) + CH + str.substring(7));
                return;
            } else if (str.length() == 10) {
                setCustomSelection(s + CH);
                return;
            } else if (str.length() == 11) {
                //按回退鍵後,再次輸入字元
setCustomSelection(str.substring(0, 10) + CH + str.substring(10));
                return;
            } else if (str.length() == 13) {
                setCustomSelection(s + CH);
                return;
            } else if (str.length() == 14) {
                //按回退鍵後,再次輸入字元
setCustomSelection(str.substring(0, 13) + CH + str.substring(13));
                return;
            } else if (str.length() == 16) {
                setCustomSelection(s + CH);
                return;
            } else if (str.length() == 17) {
                //按回退鍵後,再次輸入字元
setCustomSelection(str.substring(0, 16) + CH + str.substring(16));
                return;
            } else if (str.length() == 19) {
                setCustomSelection(s + CH);
                return;
            } else if (str.length() == 20) {
                //按回退鍵後,再次輸入字元
setCustomSelection(str.substring(0, 19) + CH + str.substring(19));
                return;
            } else if (str.length() == 22) {
                setCustomSelection(s + CH);
                return;
            } else if (str.length() == 23) {
                //按回退鍵後,再次輸入字元
setCustomSelection(str.substring(0, 22) + CH + str.substring(22));
                return;
            } else if (str.length() == 25) {
                setCustomSelection(s + CH);
                return;
            } else if (str.length() == 26) {
                //按回退鍵後,再次輸入字元
setCustomSelection(str.substring(0, 25) + CH + str.substring(25));
                return;
            } else if (str.length() == 28) {
                setCustomSelection(s + CH);
                return;
            } else if (str.length() == 29) {
                //按回退鍵後,再次輸入字元
setCustomSelection(str.substring(0, 28) + CH + str.substring(28));
                return;
            }
//            Log.e("zouguibao", "length = " + str.length());
} else {
            if (str.length() == 30 || str.length() == 29) {
                setCustomSelection(str.substring(0, 28));
                return;
            } else if (str.length() == 27 || str.length() == 26) {
                setCustomSelection(str.substring(0, 25));
                return;
            } else if (str.length() == 24 || str.length() == 23) {
                setCustomSelection(str.substring(0, 22));
                return;
            } else if (str.length() == 21 || str.length() == 20) {
                setCustomSelection(str.substring(0, 19));
                return;
            } else if (str.length() == 18 || str.length() == 17) {
                setCustomSelection(str.substring(0, 16));
                return;
            } else if (str.length() == 15 || str.length() == 14) {
                setCustomSelection(str.substring(0, 13));
                return;
            } else if (str.length() == 12 || str.length() == 11) {
                setCustomSelection(str.substring(0, 10));
                return;
            } else if (str.length() == 9 || str.length() == 8) {
                setCustomSelection(str.substring(0, 7));
                return;
            } else if (str.length() == 6 || str.length() == 5) {
                setCustomSelection(str.substring(0, 4));
                return;
            } else if (str.length() == 3 || str.length() == 2) {
                setCustomSelection(str.substring(0, 1));
                return;
            }
//            Log.e("zouguibao", "back to word index = " + str.length());
}

        tempStr = mEditText.getText().toString();


    }

    @Override
public void afterTextChanged(Editable s) {
    }


    private void setCustomSelection(String content) {
        if (!TextUtils.isEmpty(content)) {
            mEditText.setText(content);
            mEditText.setSelection(mEditText.getText().length());
        }
    }
}
以上的兩步做完基本就算是完成了,接下來是使用時的一些介紹:
<xx.VisitCodeEditText
android:id="@+id/input_visit_code_view"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@null"
android:inputType="number"
android:maxLength="31"//這個是要輸入的字元加上空格一共可輸入的字元數
android:paddingLeft="10px"
android:textColor="@color/code_click_color"
android:singleLine="true"
/>
引用時:
visitCodeEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24f);//這個必須和自定義的類裡面設定的字型大小一致,否則效果會不一致
InputVisitCodeTextWatcher inputVisitCodeTextWatcher = new InputVisitCodeTextWatcher(visitCodeEditText);
visitCodeEditText.addTextChangedListener(inputVisitCodeTextWatcher);
基本上就這些啦,如果更好的想法,歡迎交流!