Android自定義九宮格輸入框
本文實例為大家分享了Android自定義九宮格輸入框的具體代碼,供大家參考,具體內(nèi)容如下
效果
實現(xiàn)
- 繪制宮格分割線
這里我們用一個RectF
類型的數(shù)組來裝載數(shù)據(jù)。在onSizeChanged
方法中獲取到控件尺寸,經(jīng)過計算,將81個位置合適的矩形保存到數(shù)組中。
- 繪制點擊效果
在onTouchEvent
方法中監(jiān)聽手指離開事件,當(dāng)手指離開,獲取到當(dāng)前點擊區(qū)域的RectF
,并將狀態(tài)同樣保存到一個數(shù)組中。
- 繪制輸入內(nèi)容
輸入內(nèi)容利用onTextChanged
方法獲取,同樣保存到一個數(shù)組中。
- PS
控件中沒有考慮UI重建數(shù)據(jù)保存問題,使用中要注意這點~~~
這三個數(shù)組中數(shù)據(jù)一一對應(yīng),在onDraw
中,根據(jù)三個數(shù)組中數(shù)據(jù)內(nèi)容繪制界面。完成我們的自定義View。
源碼
/** ?* 自定義九宮格輸入框 ?* attrs: customTableLineColor ?宮格分割線顏色 ?* attrs: customTableLineWidth ?宮格分割線寬度 ?* attrs: customTablePressColor 宮格選中時背景顏色 ?* attrs: customTableSpace ? ? ?大宮格間隔 ?* attrs: customTableTextColor ?宮格輸入文字顏色 ?* attrs: customTableTextSize ? 宮格輸入文字大小 ?* attrs: customTableAngle ? ? ?宮格圓角尺寸 ?* 默認值請查看 {@link CustomEditText#initAttrs(Context, AttributeSet)} ?*/ public class CustomEditText extends AppCompatEditText { ? ? private static final String TAG = "CustomEditText"; ? ? //宮格位置 ? ? private final RectF[] mTableList = new RectF[81]; ? ? //宮格狀態(tài) ? ? private final Boolean[] mTableState = new Boolean[81]; ? ? //宮格數(shù)據(jù) ? ? private final Integer[] mTableListNumber = new Integer[81]; ? ? //繪制宮格畫筆 ? ? private Paint mPaint; ? ? //繪制宮格背景畫筆 ? ? private Paint mBackgroundPaint; ? ? //繪制文字畫筆 ? ? private TextPaint mTextPaint; ? ? //手指離開屏幕X軸坐標(biāo) ? ? private float mTouchX; ? ? //手指離開屏幕Y軸坐標(biāo) ? ? private float mTouchY; ? ? //表格內(nèi)文字尺寸 ? ? private float mTextSize; ? ? //表格內(nèi)文字顏色 ? ? private int mTextColor; ? ? //表格分割線顏色 ? ? private int mTableLineColor; ? ? //選中對應(yīng)宮格背景顏色 ? ? private int mTablePressColor; ? ? //表格分割線寬度 ? ? private float mTableLineWidht; ? ? //大宮格間隔 ? ? private float mTableSpace; ? ? //宮格圓角尺寸 ? ? private float mTableAngle; ? ? public CustomEditText(Context context) { ? ? ? ? this(context, null); ? ? } ? ? public CustomEditText(Context context, AttributeSet attrs) { ? ? ? ? this(context, attrs, R.attr.editTextStyle); ? ? } ? ? public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) { ? ? ? ? super(context, attrs, defStyleAttr); ? ? ? ? initAttrs(context, attrs); ? ? ? ? initSet(); ? ? ? ? initPaint(); ? ? } ? ? /** ? ? ?* 初始化自定義屬性 ? ? ?*/ ? ? private void initAttrs(Context context, AttributeSet attrs) { ? ? ? ? TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomEditText); ? ? ? ? mTextColor = typedArray.getColor(R.styleable.CustomEditText_customTableTextColor, Color.parseColor("#000000")); ? ? ? ? mTableLineColor = typedArray.getColor(R.styleable.CustomEditText_customTableLineColor, Color.parseColor("#000000")); ? ? ? ? mTablePressColor = typedArray.getColor(R.styleable.CustomEditText_customTablePressColor, Color.parseColor("#DDDDDD")); ? ? ? ? mTextSize = typedArray.getDimension(R.styleable.CustomEditText_customTableTextSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); ? ? ? ? mTableLineWidht = typedArray.getDimension(R.styleable.CustomEditText_customTableLineWidth, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics())); ? ? ? ? mTableSpace = typedArray.getDimension(R.styleable.CustomEditText_customTableSpace, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics())); ? ? ? ? mTableSpace = typedArray.getDimension(R.styleable.CustomEditText_customTableSpace, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics())); ? ? ? ? mTableAngle = typedArray.getDimension(R.styleable.CustomEditText_customTableAngle, 0); ? ? ? ? typedArray.recycle(); ? ? } ? ? /** ? ? ?* 初始化畫筆 ? ? ?*/ ? ? private void initPaint() { ? ? ? ? mBackgroundPaint = new Paint(); ? ? ? ? mBackgroundPaint.setAntiAlias(true); ? ? ? ? mBackgroundPaint.setStyle(Paint.Style.FILL); ? ? ? ? mBackgroundPaint.setColor(mTablePressColor); ? ? ? ? mPaint = new Paint(); ? ? ? ? mPaint.setAntiAlias(true); ? ? ? ? mPaint.setColor(mTableLineColor); ? ? ? ? mPaint.setStrokeWidth(mTableLineWidht); ? ? ? ? mPaint.setStyle(Paint.Style.STROKE); ? ? ? ? mTextPaint = new TextPaint(); ? ? ? ? mTextPaint.setColor(mTextColor); ? ? ? ? mTextPaint.setTextSize(mTextSize); ? ? ? ? mTextPaint.setAntiAlias(true); ? ? ? ? mTextPaint.setTextAlign(Paint.Align.CENTER); ? ? } ? ? /** ? ? ?* 初始化EditText基礎(chǔ)設(shè)置 ? ? ?*/ ? ? private void initSet() { ? ? ? ? //隱藏光標(biāo) ? ? ? ? setCursorVisible(false); ? ? ? ? //設(shè)置輸入類型 ? ? ? ? setInputType(InputType.TYPE_CLASS_NUMBER); ? ? ? ? //限制輸入一行 ? ? ? ? setSingleLine(true); ? ? } ? ? @Override ? ? protected void onDraw(Canvas canvas) { ? ? ? ? for (int i = 0; i < mTableList.length; i++) { ? ? ? ? ? ? RectF rectF = mTableList[i]; ? ? ? ? ? ? if (mTableState[i]) { ? ? ? ? ? ? ? ? //繪宮格制背景 ? ? ? ? ? ? ? ? canvas.drawRoundRect(rectF, mTableAngle, mTableAngle, mBackgroundPaint); ? ? ? ? ? ? } ? ? ? ? ? ? //繪制宮格分割線 ? ? ? ? ? ? canvas.drawRoundRect(rectF, mTableAngle, mTableAngle, mPaint); ? ? ? ? ? ? Integer integer = mTableListNumber[i]; ? ? ? ? ? ? if (integer != 0) { ? ? ? ? ? ? ? ? //測量文字尺寸 ? ? ? ? ? ? ? ? Rect measureTextSize = measureTextSize(integer + ""); ? ? ? ? ? ? ? ? //繪制輸入內(nèi)容 ? ? ? ? ? ? ? ? canvas.drawText(integer + "", rectF.centerX(), rectF.centerY() + measureTextSize.height() / 2.0F, mTextPaint); ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? @Override ? ? public boolean onTouchEvent(MotionEvent event) { ? ? ? ? if (event.getAction() == MotionEvent.ACTION_UP) {//手指離開 ? ? ? ? ? ? mTouchX = event.getX(); ? ? ? ? ? ? mTouchY = event.getY(); ? ? ? ? ? ? //檢查輸入內(nèi)容和狀態(tài)是否對應(yīng) ? ? ? ? ? ? for (int i = 0; i < mTableListNumber.length; i++) { ? ? ? ? ? ? ? ? Integer integer = mTableListNumber[i]; ? ? ? ? ? ? ? ? if (integer == 0) { ? ? ? ? ? ? ? ? ? ? //背景應(yīng)該為透明 ? ? ? ? ? ? ? ? ? ? if (mTableState[i]) { ? ? ? ? ? ? ? ? ? ? ? ? mTableState[i] = false; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? //設(shè)置選中宮格 ? ? ? ? ? ? for (int i = 0; i < mTableList.length; i++) { ? ? ? ? ? ? ? ? if (mTableList[i].contains(mTouchX, mTouchY)) { ? ? ? ? ? ? ? ? ? ? mTableState[i] = true; ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? if (event.getAction() == MotionEvent.ACTION_DOWN) { ? ? ? ? ? ? performClick(); ? ? ? ? } ? ? ? ? return super.onTouchEvent(event); ? ? } ? ? @Override ? ? public boolean performClick() { ? ? ? ? return super.performClick(); ? ? } ? ? @Override ? ? protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { ? ? ? ? super.onTextChanged(text, start, lengthBefore, lengthAfter); ? ? ? ? String trim = text.toString().trim(); ? ? ? ? if (!TextUtils.isEmpty(trim) && TextUtils.isDigitsOnly(trim)) { ? ? ? ? ? ? //保存輸入內(nèi)容 ? ? ? ? ? ? if (trim.length() > 1) { ? ? ? ? ? ? ? ? trim = trim.substring(trim.length() - 1, trim.length()); ? ? ? ? ? ? } ? ? ? ? ? ? for (int i = 0; i < mTableList.length; i++) { ? ? ? ? ? ? ? ? if (mTableList[i].contains(mTouchX, mTouchY)) { ? ? ? ? ? ? ? ? ? ? mTableListNumber[i] = Integer.parseInt(trim); ? ? ? ? ? ? ? ? ? ? //修改宮格背景狀態(tài) ? ? ? ? ? ? ? ? ? ? mTableState[i] = true; ? ? ? ? ? ? ? ? ? ? //清空默認EditText輸入內(nèi)容 ? ? ? ? ? ? ? ? ? ? CustomEditText.this.setText(""); ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? @Override ? ? protected void onSizeChanged(int w, int h, int oldw, int oldh) { ? ? ? ? super.onSizeChanged(w, h, oldw, oldh); ? ? ? ? //初始化宮格位置數(shù)據(jù) ? ? ? ? int paddingLeft = getPaddingLeft(); ? ? ? ? int paddingRight = getPaddingRight(); ? ? ? ? int paddingTop = getPaddingTop(); ? ? ? ? int measuredWidth = getMeasuredWidth(); ? ? ? ? //表格實際顯示的寬度 ? ? ? ? int tableWidht = (int) (measuredWidth - mTableSpace * 2 - paddingLeft - paddingRight); ? ? ? ? //每個表格的寬度 ? ? ? ? float singleTableWidth = tableWidht / 3.0F; ? ? ? ? for (int i = 0; i < 9; i++) { ? ? ? ? ? ? float top; ? ? ? ? ? ? float left; ? ? ? ? ? ? float bottom; ? ? ? ? ? ? float right; ? ? ? ? ? ? left = paddingLeft + (singleTableWidth * (i % 3)) + (mTableSpace * (i % 3)); ? ? ? ? ? ? right = left + singleTableWidth; ? ? ? ? ? ? top = paddingTop + (singleTableWidth * (i / 3)) + (mTableSpace * (i / 3)); ? ? ? ? ? ? bottom = top + singleTableWidth; ? ? ? ? ? ? //最大九個宮格的矩形 ? ? ? ? ? ? RectF rectF = new RectF(left, top, right, bottom); ? ? ? ? ? ? float width = rectF.width(); ? ? ? ? ? ? float singleTableWidthMin = width / 3.0F; ? ? ? ? ? ? for (int j = 0; j < 9; j++) { ? ? ? ? ? ? ? ? float topMin; ? ? ? ? ? ? ? ? float leftMin; ? ? ? ? ? ? ? ? float bottomMin; ? ? ? ? ? ? ? ? float rightMin; ? ? ? ? ? ? ? ? leftMin = singleTableWidthMin * (j % 3) + rectF.left; ? ? ? ? ? ? ? ? rightMin = leftMin + singleTableWidthMin; ? ? ? ? ? ? ? ? topMin = singleTableWidthMin * (j / 3) + rectF.top; ? ? ? ? ? ? ? ? bottomMin = topMin + singleTableWidthMin; ? ? ? ? ? ? ? ? //每個小宮格的矩形 ? ? ? ? ? ? ? ? RectF rectFMin = new RectF(leftMin, topMin, rightMin, bottomMin); ? ? ? ? ? ? ? ? for (int k = 0; k < mTableList.length; k++) { ? ? ? ? ? ? ? ? ? ? if (mTableList[k] == null) { ? ? ? ? ? ? ? ? ? ? ? ? mTableList[k] = rectFMin; ? ? ? ? ? ? ? ? ? ? ? ? mTableListNumber[k] = 0; ? ? ? ? ? ? ? ? ? ? ? ? mTableState[k] = false; ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? @Override ? ? protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ? ? ? ? //強制控件為正方形 ? ? ? ? super.onMeasure(widthMeasureSpec, widthMeasureSpec); ? ? } ? ? /** ? ? ?* 測量文字的尺寸 ? ? ?* ? ? ?* @return 一個漢字的矩陣 ? ? ?*/ ? ? private Rect measureTextSize(String content) { ? ? ? ? Rect mRect = null; ? ? ? ? if (!TextUtils.isEmpty(content)) { ? ? ? ? ? ? if (mTextPaint != null) { ? ? ? ? ? ? ? ? mRect = new Rect(); ? ? ? ? ? ? ? ? mTextPaint.getTextBounds(content, 0, content.length(), mRect); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return mRect; ? ? } }
自定義屬性
<resources> ? ? <declare-styleable name="CustomEditText"> ? ? ? ? <attr name="customTableTextSize" format="dimension" /> ? ? ? ? <attr name="customTableTextColor" format="color" /> ? ? ? ? <attr name="customTableLineColor" format="color" /> ? ? ? ? <attr name="customTableLineWidth" format="dimension" /> ? ? ? ? <attr name="customTableSpace" format="dimension" /> ? ? ? ? <attr name="customTablePressColor" format="color"/> ? ? ? ? <attr name="customTableAngle" format="integer"/> ? ? </declare-styleable> </resources>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 5種方法完美解決android軟鍵盤擋住輸入框方法詳解
- Android高級xml布局之輸入框EditText設(shè)計
- Android文本輸入框(EditText)輸入密碼時顯示與隱藏
- Android實現(xiàn)動態(tài)顯示或隱藏密碼輸入框的內(nèi)容
- 解決Android軟鍵盤彈出覆蓋h5頁面輸入框問題
- Android軟鍵盤擋住輸入框的終極解決方案
- Android仿支付寶自定義密碼輸入框及安全鍵盤(密碼鍵盤)
- Android 自定義密碼輸入框?qū)崿F(xiàn)代碼
- Android實現(xiàn)常見的驗證碼輸入框?qū)嵗a
- Android UI設(shè)計系列之自定義EditText實現(xiàn)帶清除功能的輸入框(3)
相關(guān)文章
Android給自定義按鍵添加廣播和通過廣播給當(dāng)前焦點輸入框賦值
這篇文章主要介紹了Android給自定義按鍵添加廣播和通過廣播給當(dāng)前焦點輸入框賦值的相關(guān)資料,需要的朋友可以參考下2016-10-10Android系統(tǒng)聯(lián)系人全特效實現(xiàn)(上)分組導(dǎo)航和擠壓動畫(附源碼)
本文將為大家講解下Android系統(tǒng)聯(lián)系人全特效實現(xiàn)之分組導(dǎo)航和擠壓動畫,具體實現(xiàn)及源代碼如下,感興趣的朋友可以參考下哈,希望對大家學(xué)習(xí)有所幫助2013-06-06Android中實現(xiàn)WebView和JavaScript的互相調(diào)用詳解
這篇文章主要給大家介紹了關(guān)于Android中實現(xiàn)WebView和JavaScript的互相調(diào)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友下面來一起看看吧。2018-03-03android開發(fā)教程之實現(xiàn)listview下拉刷新和上拉刷新效果
這篇文章主要介紹了android實現(xiàn)listview下拉刷新和上拉刷新效果,Android的ListView上拉下拉刷新,原理都一樣,在Touch事件中操作header/footer的paddingTop屬性,需要的朋友可以參考下2014-02-02Android開發(fā)中ImageLoder加載網(wǎng)絡(luò)圖片時將圖片設(shè)置為ImageView背景的方法
這篇文章主要介紹了Android開發(fā)中ImageLoder加載網(wǎng)絡(luò)圖片時將圖片設(shè)置為ImageView背景的方法,涉及Android ImageView圖片加載及背景設(shè)置相關(guān)操作技巧,需要的朋友可以參考下2018-01-01Android傳遞Bitmap對象在兩個Activity之間
這篇文章主要介紹了Android傳遞Bitmap對象在兩個Activity之間的相關(guān)資料,需要的朋友可以參考下2016-01-01