1. 程式人生 > >自定義控制元件起步(三)--自定義驗證碼(上)

自定義控制元件起步(三)--自定義驗證碼(上)

自定義控制元件前兩篇主要介紹了自定義控制元件的步驟和自定義屬性,這篇我門來寫一個自定義驗證碼

首先,先分析分析我門需要什麼:

      自定義驗證碼,我門需要先畫一段文字,準確的說是四個數字或字母,還需要一個灰色的背景.

      說的詳細點,我門需要一個驗證碼字型顏色 ,字型大小.字型的內容我門先寫死,等內容畫出

      來了,我門在程式碼中結合隨機數生成

接下來,我門看具體步驟

    1.宣告兩個自定義屬性   分別是驗證碼字型顏色和字型大小

     在values下建立一個attrs的xml資料夾,在<resources>中新增自定義屬性

    <declare-styleable name="securitycode">
        <attr name="security_text_color" format="color" />
        <attr name="security_text_size" format="dimension" />
    </declare-styleable>
    2.建立自定義控制元件類SecurityCodeView,繼承view,宣告三個構造方法,這跟之前的一樣
        public SecurityCodeView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}
	public SecurityCodeView(Context context) {
		this(context, null, 0);
	}
        public SecurityCodeView(Context context, AttributeSet attrs,
            int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        }
     3.使用自定義屬性
        先宣告名稱空間   xmlns:dsecurity="http://schemas.android.com/apk/res/com.example.defindedsecuritycode"
       
            <com.example.defindedsecuritycode.SecurityCodeView
                android:id="@+id/security_code"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                dsecurity:security_text_color="#999999"
                dsecurity:security_text_size="40sp">
            </com.example.defindedsecuritycode.SecurityCodeView>
    4.在構造方法中獲取自定義屬性  
                // 獲取自定義屬性值 驗證碼字型顏色,大小,內容
		TypedArray typedArray = context.getTheme().obtainStyledAttributes(
				attrs, R.styleable.securitycode, defStyleAttr, 0);
                security_color = typedArray.getColor(
                R.styleable.securitycode_security_text_color, Color.BLACK);
           security_size = typedArray.getDimensionPixelSize(
                R.styleable.securitycode_security_text_size, (int) TypedValue
                        .applyDimension(TypedValue.COMPLEX_UNIT_SP, 16,
                                getResources().getDisplayMetrics()));
        typedArray.recycle();//一定記得回收
     5.在構造方法中進行一些初始化操作
             Paint mPaint  = new Paint();// 建立畫筆
        mPaint.setTextSize(security_size);// 設定字型大小
        security_rect = new Rect();// 建立一個矩形
        mPaint.getTextBounds(security_text, 0, security_text.length(),
                security_rect);// 根據文字的大小設定矩形的大小();// 建立畫筆
           String security_text="";//這裡我們先把驗證碼的文字寫死

      這裡建立的這個矩形就是等會我們要畫的灰色陰影部分,我們根據文字字型的大小和文字的長度來設定陰影部分矩形的大小

      6.測量控制元件的大小

	/**
	 * 測量大小 根據寬或者高的模式來確定自定義控制元件大小
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		int heightSize = MeasureSpec.getSize(heightMeasureSpec);
		int width;
		int height;
		if (widthMode == MeasureSpec.EXACTLY) {// 如果確定大小 不用計算
			width = widthSize;
		} else {// 大小不確定 根據驗證碼的寬度來確定
			mPaint.setTextSize(security_size);
			mPaint.getTextBounds(security_text, 0, security_text.length(),
					security_rect);
			int textWidth = security_rect.width();
			int realWidth = textWidth + getPaddingLeft() + getPaddingRight();
			width = realWidth;
		}
		if (heightMode == MeasureSpec.EXACTLY) {
			height = heightSize;
		} else {
			mPaint.setTextSize(security_size);
			mPaint.getTextBounds(security_text, 0, security_text.length(),
					security_rect);
			int textheight = security_rect.height();
			int realHeight = textheight + getPaddingBottom() + getPaddingTop();
			height = realHeight;
		}
		setMeasuredDimension(width, height);// 將確定好的長和寬告設定上去
	}
            注意:這裡我們根據文字的大小和長度來測量控制元件的大小

       7.開始畫我們的自定控制元件(非常關鍵的一步)

                // 設定驗證碼背景顏色,並畫出來
		mPaint.setColor(Color.parseColor("#e1e1e1"));//背景顏色是灰色的,直接寫死
		canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);

		// 設定驗證碼顏色,並畫出來
		mPaint.setColor(security_color);
		canvas.drawText(security_text, getWidth() / 2 - security_rect.width()
				/ 2, getHeight() / 2 + security_rect.height() / 2, mPaint);
       問題一:為什麼矩形的寬度和高度等同於整個控制元件的高度?

     這裡的矩形,實際上是我們看到的陰影部分,陰影部分的高度是大於文字的高度的,陰影部分的高度也是整個驗證碼的高度

       問題二:字型的高度和寬度  

   

           注意:因為咱們重寫了onMeasure方法,所以,測量的寬度getMeasuredWidth和getWidth()是一樣的

       問題三:我能不能先畫文字,再畫背景?

       不能,如果先畫文字再畫背景,背景會把文字遮住的,我們就只能看到背景,而看不到文字了

    8.執行,,看一下效果吧


    到這裡我們自定義驗證碼的雛形就顯示出來了,但是還有幾個問題,怎麼設定驗證碼的了型別,點選切換等,這些下一篇會介紹

   點選這裡下載原始碼