@ZeroGeek
2015-08-18T02:29:47.000000Z
字数 4173
阅读 870
view android
参考:
http://blog.csdn.net/guolin_blog/article/details/17357967 郭霖的View系列文章(1~4)
http://www.codekk.com/open-source-project-analysis/detail/Android/lightSky/%E5%85%AC%E5%85%B1%E6%8A%80%E6%9C%AF%E7%82%B9%E4%B9%8B%20View%20%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B View绘制流程的源码解析
如果不能理解这个,很难自己定义出无Bug的View.
每一个视图的绘制过程都必须经历三个最主要的阶段,即onMeasure()、onLayout()和onDraw()。
测量,确定位置,绘制。
public class MyView extends View {......@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(200, 200);}}
这样的话就把View默认的测量流程覆盖掉了,不管在布局文件中定义MyView这个视图的大小是多少,最终在界面上显示的大小都将会是200*200。
需要注意的是,在setMeasuredDimension()方法调用之后,我们才能使用getMeasuredWidth()和getMeasuredHeight()来获取视图测量出的宽高,以此之前调用这两个方法得到的值都会是0。
由此可见,视图大小的控制是由父视图、布局文件、以及视图本身共同完成的,父视图会提供给子视图参考的大小,而开发人员可以在XML文件中指定视图的大小,然后视图本身会对最终的大小进行拍板。
OnMeasure()比较容易理解,对于刚入门来说,先好好学习onDraw(),Canvas和Paint的一些用法,一般不会用到onLayout()。
package com.zero.apptest;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.util.AttributeSet;import android.view.View;/*** 简易点赞计数器* Created by zero on 15-8-18.*/public class ClickCountView extends View implements View.OnClickListener{private Paint mPaint; //画笔private Rect mBounds; //用来包裹文本的矩形,计算中心,居中显示private static int mCount = 0; //统计点击的次数private boolean isClicked; //判断点赞或取消public ClickCountView(Context context) {super(context);initView();}public ClickCountView(Context context, AttributeSet attrs) {super(context, attrs);initView();}public ClickCountView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initView();}private void initView() {isClicked = false;setOnClickListener(this);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mPaint = new Paint();mBounds = new Rect();mPaint.setColor(Color.parseColor("#1ABC9C"));canvas.drawCircle(100, 100, 100, mPaint); //绘制坐标为(100,100),半径为100的圆(第三参数为半径)mPaint.setTextSize(100);String text = String.valueOf(mCount);mPaint.getTextBounds(text, 0, text.length(), mBounds);mPaint.setColor(Color.parseColor("#7F8C8D"));final float textWidth = mBounds.width();final float textHeight = mBounds.height();//绘制文本,居中显示canvas.drawText(Integer.toString(mCount), getWidth()/2 - textWidth/2, getHeight()/2 + textHeight/2, mPaint);}/***限制大小,无论xml中如何设置,都为200*200*/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(200,200);}@Overridepublic void onClick(View v) {if (!isClicked) {mCount++;isClicked = true;} else {mCount--;isClicked = false;}//每次点击后,重绘视图invalidate();}}
main.xml 代码:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><com.zero.apptest.ClickCountViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center" /><com.zero.apptest.ClickCountViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center" /><com.zero.apptest.ClickCountViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center" /><com.zero.apptest.ClickCountViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center" /></LinearLayout>
尝试运行下吧,哈哈,看看是否如下:
