自定義虛線格式的EditText輸入框
阿新 • • 發佈:2019-01-01
好久沒有寫部落格,是覺得沒有太多的東西可寫,今天分享一下,自定義edittext的輸入框,效果圖如下:
這個效果是一個輸入11位手機號的效果圖,分為兩個步驟實現:
1.畫出虛線,確定寬度和高度
2.控制焦點的定位。
虛線並不是一個圖片,而是繼承了EditText後,畫出來的,具體的程式碼如下:
public class VisitCodeEditText extends EditText { private Paint paint; private Paint textPaint; private int perDashWidth; private intperGapWidth; 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, intdefStyleAttr) { 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);
基本上就這些啦,如果更好的想法,歡迎交流!