【安卓深度控件开发(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>

相关文章
相关标签/搜索