【安卓深度控件開發(2.1)】LCDView - 基本繪圖

<p>好了,今天咱們來真正本身動手製做控件了,在本章中咱們會從最簡單開始。雖然是簡單,但你必須已經能本身作 Activity 等最基本的東西。</p> <p>注意,我不會:</p> <ol> <li>控件中不會使用任何 res/ 下的文件支持,由於這對於爲本身創建一個控件庫來講不是必須的,相反它讓設計變的複雜,作一個簡單的控件在多個文件中跳來跳去可不是什麼好玩的事,特別是將來你須要把控件複製到你的項目中使用時,若是隻須要複製一個 .java 文件是多麼簡單,你不用爲了複製相關副屬資源文件找來找去了,不是嗎。固然,若是你的確須要設計時能設定一大堆本身的屬性什麼的,你徹底能夠按第一章提到的方式去實現。 </li> <li>不會使用太多 Android 框架下的幫助類與方法,由於我也在看呢 :)。若是必定要找個理由來講的話,我相信專爲控件而定製的幫助方法必定比通用版本的簡單,從而更有效率。 </li> <li>從第一章到最後一章,幾乎不會找到有一個函數始終是同樣的。由於咱們是從簡單開始,但最後,咱們但願的是實用好用,而不是個 TEST 而已。 </li> <li>我不會寫大堆的文字說明來解析每一行代碼,由於大部分東西我已經以註釋的樣式寫在代碼裏了。我不須要你忘記了什麼以後再來的點擊量 :) </li> </ol> <p>&#160;</p> <h2>目標</h2> <p>來講說咱們此次是目標 – LCDView。</p> <p>從名字能夠看出,它是一個模擬 LCD 效果的視圖或直白說成是模擬點陣屏幕好了。</p> <p>&#160;</p> <h2>版本一</h2> <p>首先按您喜歡的名稱建立一個新的 Android 項目,而後新建一個類 LCDView,實現以下:</p> <div> <pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> LCDView <span style="color: #0000ff">extends</span> View {java

<span style="color: #0000ff">private</span> String text = &quot;<span style="color: #8b0000">LCD 自定義視圖</span>&quot;;
<span style="color: #0000ff">private</span> Paint mTextPaint = <span style="color: #0000ff">new</span> Paint();
<span style="color: #0000ff">private</span> Paint mLinePaint = <span style="color: #0000ff">new</span> Paint();
<span style="color: #0000ff">private</span> Rect mBounds = <span style="color: #0000ff">new</span> Rect();
<span style="color: #0000ff">private</span> Point mTextPos = <span style="color: #0000ff">new</span> Point();
<span style="color: #0000ff">private</span> Rect mTextBounds = <span style="color: #0000ff">new</span> Rect();

<span style="color: #0000ff">public</span> LCDView(Context context, AttributeSet attrs) {
	<span style="color: #0000ff">super</span>(context, attrs);		
	init();
}

<span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> init() {
	<span style="color: #008000">// 默認背景爲黑色</span>
	setBackgroundColor(Color.BLACK);
	mLinePaint.setColor(0xcc000000);
	mLinePaint.setStyle(Style.STROKE);
	mLinePaint.setStrokeWidth(1);
	
	<span style="color: #008000">// 默認文本爲白色</span>
	mTextPaint.setColor(Color.WHITE);
	mTextPaint.setTextSize(36);
	mTextPaint.setTextAlign(Align.CENTER);
}

@Override
<span style="color: #0000ff">protected</span> <span style="color: #0000ff">void</span> onSizeChanged(<span style="color: #0000ff">int</span> w, <span style="color: #0000ff">int</span> h, <span style="color: #0000ff">int</span> oldw, <span style="color: #0000ff">int</span> oldh) {
	<span style="color: #0000ff">super</span>.onSizeChanged(w, h, oldw, oldh);
	<span style="color: #008000">// 計算咱們可能用於繪製內容的區域</span>
	mBounds.set(getPaddingLeft(), getPaddingTop(), w - getPaddingLeft() - getPaddingRight(), h - getPaddingTop() - getPaddingBottom());		
	recalcTextPoint();
}

<span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> recalcTextPoint() {
	<span style="color: #008000">// 咱們將在視圖的正中間繪製文本,這裏計算文本須要繪製的位置</span>
	<span style="color: #0000ff">int</span> textHeight = 0;
	<span style="color: #0000ff">if</span>(text != <span style="color: #0000ff">null</span> &amp;&amp; !text.isEmpty()) {
		mTextPaint.getTextBounds(text, 0, 1, mTextBounds);
		textHeight = mTextBounds.height();
	}
	mTextPos.x = mBounds.centerX();
	mTextPos.y = mBounds.centerY() + (textHeight / 2);		
}

@Override
<span style="color: #0000ff">protected</span> <span style="color: #0000ff">void</span> onDraw(Canvas canvas) {
	<span style="color: #0000ff">super</span>.onDraw(canvas);
	<span style="color: #0000ff">if</span>(text == <span style="color: #0000ff">null</span> &amp;&amp; text.isEmpty()) {
		<span style="color: #0000ff">return</span>;
	}		
	canvas.drawText(text, mTextPos.x, mTextPos.y, mTextPaint);
	
	<span style="color: #008000">// 至關直接的作法,後面將變不少次</span>
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> y=mBounds.top; y&lt;mBounds.bottom; y+=2) {
		canvas.drawLine(mBounds.left, y, mBounds.right, y, mLinePaint);
	}
}

<span style="color: #008000">/***** 公共用戶屬性 *****/</span>

<span style="color: #008000">/**
 * 獲取當前顯示文本
 * @return
 */</span>
<span style="color: #0000ff">public</span> String getText() {
	<span style="color: #0000ff">return</span> text;
}

<span style="color: #008000">/**
 * 設置要顯示的文本
 * @param text
 */</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setText(String text) {
	<span style="color: #0000ff">this</span>.text = text;
	recalcTextPoint();
	invalidate();
}

<span style="color: #008000">/**
 * 獲取當前文本顏色
 * @return
 */</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> getTextColor() {
	<span style="color: #0000ff">return</span> mTextPaint.getColor();
}

<span style="color: #008000">/**
 * 設置當前文本顏色
 * @param color
 */</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setTextColor(<span style="color: #0000ff">int</span> color) {
	mTextPaint.setColor(color);
	invalidate();
}

<span style="color: #008000">/**
 * 獲取當前文本字體大小
 * @return
 */</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">float</span> getTextSize() {
	<span style="color: #0000ff">return</span> mTextPaint.getTextSize();
}

<span style="color: #008000">/**
 * 設置當前文本字體大小
 * @param textSize
 */</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setTextSize(<span style="color: #0000ff">float</span> textSize) {
	mTextPaint.setTextSize(textSize);
	recalcTextPoint();
	invalidate();
}

}</pre>canvas

</div>框架

<br />ide

<p>完成了,它就是一個可用的視圖了,打開 activity_main.xml 點左邊的 「Custom &amp; Library Views」而後點面板底部的 「Refresh」,看到它了吧,像通常自帶控件同樣,拖到設計界面裏去,而後運行看看效果。</p>函數

<p>在主要的繪圖代碼裏,咱們經過繪製間隔爲一個像素的半透明黑色橫向線條,讓它看起來像 LCD 同樣了。</p>字體

<p>能夠看到在幾個給用戶操做的 setter 中,有些調用了 recalcTextPoint() 與 invalidate(),而有些只調用了 invalidate() ,原則是隻幹你須要乾的事,多的事咱不幹~~~</p>this

<p>如今讓咱們在添加一個按鈕看看 setter 有木有效果:</p>spa

<ol> <li>再拖一個按鈕到設計界面,修改 id 爲 「buttonChangeColor」 </li>設計

<li>切換到 MainActivity.java ,在 onCreate 以前加入以下代碼: <div style="border-bottom: #ddd 1px solid; border-left: #ddd 1px solid; padding-bottom: 1em; margin: 0px 0px 1em; padding-left: 1em; padding-right: 1em; background: #f7f7f7; overflow: auto; border-top: #ddd 1px solid; border-right: #ddd 1px solid; padding-top: 1em"> <pre> <span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">final</span> <span style="color: #0000ff">int</span>[] colors = <span style="color: #0000ff">new</span> <span style="color: #0000ff">int</span>[]{ Color.WHITE, Color.BLUE, Color.GREEN, Color.RED, Color.YELLOW };code

<span style="color: #0000ff">private</span> <span style="color: #0000ff">int</span> colorIndex = 0;

<span style="color: #0000ff">private</span> LCDView lcd;</pre>
</div>

</li>

<li>在 onCreate 內部的尾部加入加入代碼: <div style="border-bottom: #ddd 1px solid; border-left: #ddd 1px solid; padding-bottom: 1em; margin: 0px 0px 1em; padding-left: 1em; padding-right: 1em; background: #f7f7f7; overflow: auto; border-top: #ddd 1px solid; border-right: #ddd 1px solid; padding-top: 1em"> <pre> lcd = (LCDView)findViewById(R.id.lCDView1); findViewById(R.id.buttonChangeColor).setOnClickListener(<span style="color: #0000ff">this</span>);</pre> </div> </li>

<li>爲 MainActivity 類實現 OnClickListener 接口,添加實現函數: <div style="border-bottom: #ddd 1px solid; border-left: #ddd 1px solid; padding-bottom: 1em; margin: 0px 0px 1em; padding-left: 1em; padding-right: 1em; background: #f7f7f7; overflow: auto; border-top: #ddd 1px solid; border-right: #ddd 1px solid; padding-top: 1em"> <pre> @Override <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> onClick(View v) { colorIndex++; colorIndex%=colors.length; lcd.setTextColor(colors[colorIndex]); }</pre> </div> </li>

<li>運行。 </li> </ol>

<p>好了,點擊按鈕試試,每一次點擊文本顏色在白,藍,綠,紅,黃中轉換,看起來還不錯。</p>

<p>目前這個代碼有兩個問題,一個是若是用戶調用 setBackgroundColor 修改了背景色,你的線條就曝光了;另外一個問題,用 for 循環去畫直線條這過低層次了,咱們將在下一節中完善。 </p>

相關文章
相關標籤/搜索