Android自定義View---驗證碼
之前學自定義View的時候,都是看一些部落格文章,然後下載相關demo去學習。但是時間久了,再重新提起自定View,還是很模糊,想寫個自定View一時還不知從哪下手。實在慚愧。
現在想在這裡記錄一下每一次學習自定View的過程。方便以後檢視,反思和總結。算是一種積累吧,不然過段時間又忘了,又得去找資源。而通過記錄,可以回翻,溫故而知新,說不定能糾正自己以前的錯誤理解呢。
嗯,那,就開始了。
這篇主要是記錄一下:看完這篇文章後(鴻洋大神寫的)https://blog.csdn.net/lmj623565791/article/details/24252901,覺得例子雖然不難,但是對整個自定義過程寫得很清楚。特此記錄。
首先先了解一下自定義View的步驟吧:
1.自定義View的屬性
2.在View的構造方法中獲得我們自定義的屬性
3.重寫onMesure(此步驟不一定是必須的,但大多數情況下還是需要重寫的)
4.重寫onDraw
1.自定義View的屬性
在res/values/下新建attrs.xml,在裡面定義屬性和宣告樣式
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="titleText" format="string" />
<attr name="titleTextColor" format="color" />
<attr name="titleTextSize" format="dimension" />
<declare-styleable name="CustomTitleView">
<attr name="titleText" />
<attr name="titleTextColor" />
<attr name="titleTextSize" />
</declare-styleable>
</resources
屬性取值型別有以下幾種:string,color,demension,integer,enum,reference,float,boolean,fraction,flag
接著在佈局中宣告我們的自定義View
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.customview01.view.CustomTitleView
android:layout_width="200dp"
android:layout_height="100dp"
custom:titleText="3712"
custom:titleTextColor="#ff0000"
custom:titleTextSize="40sp" />
</RelativeLayout>
一定要引入 xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"我們的名稱空間,後面的包路徑指的是專案的package
2.在View的構造方法中,獲得我們的自定義的樣式和屬性
/**
* 文字
*/
private String mTitleText;
/**
* 文字的顏色
*/
private int mTitleTextColor;
/**
* 文字的大小
*/
private int mTitleTextSize;
/**
* 繪製時控制文字繪製的範圍
*/
private Rect mBound;
private Paint mPaint;
public CustomTitleView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public CustomTitleView(Context context)
{
this(context, null);
}
/**
* 獲得我自定義的樣式屬性
*
* @param context
* @param attrs
* @param defStyle
*/
public CustomTitleView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
/**
* 獲得我們所定義的自定義樣式屬性
*/
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.CustomTitleView_titleText:
mTitleText = a.getString(attr);
break;
case R.styleable.CustomTitleView_titleTextColor:
// 預設顏色設定為黑色
mTitleTextColor = a.getColor(attr, Color.BLACK);
break;
case R.styleable.CustomTitleView_titleTextSize:
// 預設設定為16sp,TypeValue也可以把sp轉化為px
mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
/**
* 獲得繪製文字的寬和高
*/
mPaint = new Paint();
mPaint.setTextSize(mTitleTextSize);
// mPaint.setColor(mTitleTextColor);
mBound = new Rect();
mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
}
我們重寫了3個構造方法,預設的佈局檔案呼叫的是兩個引數的構造方法,所以記得讓所有的構造呼叫我們的三個引數的構造,我們在三個引數的構造中獲得自定義屬性。
3.重寫onDraw,onMeasure呼叫系統提供的
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas)
{
mPaint.setColor(Color.YELLOW);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
mPaint.setColor(mTitleTextColor);
canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);
}
效果如下:
但現在有一個問題,當我們把佈局檔案中該View的寬高改為wrap_content的時候,效果如下(像系統控制元件TextView和Button等,即使寬高設定wrap_content,但是我們會發現它們也是有一個預設的大小的):
系統幫我們測量的高度和寬度都是MATCH_PARNET,當我們設定明確的寬度和高度時,系統幫我們測量的結果就是我們設定的結果,當我們設定為WRAP_CONTENT,或者MATCH_PARENT系統幫我們測量的結果就是MATCH_PARENT的長度。
所以我們需要重寫onMeasure方法,來處理WRAP_CONTENT的情況。
@Override
protected void onMeasure(int widthMeasureSpec, int 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(mTitleTextSize);
mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBounds);
float textWidth = mBounds.width();
int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
width = desired;
}
if (heightMode == MeasureSpec.EXACTLY)
{
height = heightSize;
} else
{
mPaint.setTextSize(mTitleTextSize);
mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBounds);
float textHeight = mBounds.height();
int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());
height = desired;
}
setMeasuredDimension(width, height);
}
修改後效果:
4.為View新增點選事件
在構造方法中新增:
this.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
mTitleText = randomText();
postInvalidate();
}
});
隨機生成四個數:
private String randomText()
{
Random random = new Random();
Set<Integer> set = new HashSet<Integer>();
while (set.size() < 4)
{
int randomInt = random.nextInt(10);
set.add(randomInt);
}
StringBuffer sb = new StringBuffer();
for (Integer i : set)
{
sb.append("" + i);
}
return sb.toString();
}
好了,記錄到此結束。自己的思路果然清晰了很多~~
再次提供原文連結:
Android 自定義View (一) - CSDN部落格 https://blog.csdn.net/lmj623565791/article/details/24252901
送上原始碼:https://github.com/huangyula/CustomView.git
相關文章
- Android自定義方形驗證碼輸入框Android
- Android View篇之自定義驗證碼輸入框AndroidView
- Laravel 自定義表單驗證-自定義驗證規則Laravel
- 自定義密碼驗證函式密碼函式
- Android開發之自定義隨機驗證碼控制元件Android隨機控制元件
- Layui 自定義表單驗證UI
- MVC驗證02-自定義驗證規則、郵件驗證MVC
- android自定義鍵盤 自定義身份證鍵盤Android
- MVC驗證07-自定義Model級別驗證MVC
- 【Laravel】 自定義配置你的密碼驗證規則Laravel密碼
- [Laravel] 自定義配置你的密碼驗證規則Laravel密碼
- MVC驗證04-自定義驗證規則、日期範圍驗證MVC
- 自定義react資料驗證元件React元件
- CAS自定義登入驗證方法
- mongoose使用validate驗證, 獲取自定義驗證資訊Go
- PbootCMS如何取消後臺、留言、自定義表單驗證碼boot
- pbootcms提交留言、提交自定義表單時取消驗證碼boot
- 表單驗證自定義格式輸出
- gin自定義驗證器&轉化中文
- django 自定義登入驗證邏輯Django
- Angular 4.x 自定義驗證指令Angular
- HTML5 pattern自定義驗證提示HTML
- jQuery Validate自定義驗證成功資訊jQuery
- jQueryValidate自定義各種驗證方法jQuery
- 自定義基於XML的驗證器XML
- MVC驗證05-自定義驗證規則、驗證2個屬性值不等MVC
- Laravel 自定義表單請求驗證忽略某些欄位驗證Laravel
- Laravel 自定義驗證規則的問題Laravel
- HTML5 pattern自定義驗證規則HTML
- jQuery Validate自定義驗證錯誤資訊jQuery
- jQuery Validate新增自定義驗證規則jQuery
- gRPC(七)進階:自定義身份驗證RPC
- MVC驗證06-自定義錯誤資訊MVC
- MVC驗證03-自定義驗證規則、禁止輸入某些值MVC
- 直播平臺原始碼,flutter 自定義九宮格,計算器佈局,驗證碼認證原始碼Flutter
- 直播系統app原始碼,自定義九宮格,計算器佈局,驗證碼認證APP原始碼
- thinkphp驗證器獲取$data資料,自定義驗證,多條件唯一性驗證unique驗證PHP
- 驗證裡,PHP 檔案中指定自定義值PHP