参考:http://www.cnblogs.com/0616--ataozhijia/p/4003380.html和http://www.open-open.com/lib/view/open1356693446838.html
运行的结果如下:
一.自定义的类继承view
<pre name="code" class="java">
package com.zhang.customview; /** * 复杂的一点自定义控件(onDraw(),onMear()) * zhangwei */ import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.text.style.LineHeightSpan.WithDensity; import android.util.AttributeSet; import android.view.View; public class FuZaZiDingYi extends View { private int mColor=Color.RED; private Paint mPaint=new Paint(Paint.ANTI_ALIAS_FLAG); public FuZaZiDingYi(Context context) { super(context); } public FuZaZiDingYi(Context context, AttributeSet attrs) { super(context, attrs); } public FuZaZiDingYi(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } //重写onDraw()方法 /** * onDraw()是个空函数,也就是说具体的视图都要覆写该函数来实现自己的显示(比如TextView在这里实现了绘制文字的过程)。 */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(mColor); final int paddingLeft=getPaddingLeft(); final int paddingRight=getPaddingRight(); final int paddingTop=getPaddingLeft(); final int paddingBootom=getPaddingLeft(); int width=getWidth()-paddingLeft-paddingRight;//宽 int height=getHeight()-paddingTop-paddingBootom;//高 int radius=Math.min(width, height)/2; canvas.drawCircle(paddingLeft+width/2,paddingTop +height/2, radius, mPaint); } //重写onMeasure()方法 /** * 视图大小的将在这里最终确定,也就是说onMeasure()方法实现自己的计算视图大小的方式, * 并通过setMeasuredDimension(width, height)保存计算结果。 * onMeasure传入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸数值,而是将模式和尺寸组合在一起的数值。 * mode共有三种情况,取值分别为MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。 * <一> MeasureSpec.EXACTLY是精确尺寸, * 当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width="50dip",或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸。 * <二> MeasureSpec.AT_MOST是最大尺寸, * 当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。 * <三> MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecMode=MeasureSpec.getMode(widthMeasureSpec);//得到模式 int widthSpecSize=MeasureSpec.getSize(widthMeasureSpec);//得到尺寸 int heightSpecMode=MeasureSpec.getMode(heightMeasureSpec); int heightSpecSize=MeasureSpec.getSize(heightMeasureSpec); if(widthSpecMode==MeasureSpec.AT_MOST && heightSpecMode==MeasureSpec.AT_MOST){ setMeasuredDimension(200, 200);//设置实际大小。 }else if (widthSpecMode==widthSpecMode) { setMeasuredDimension(200, heightSpecSize); }else if (heightSpecMode==MeasureSpec.AT_MOST) { setMeasuredDimension(widthSpecSize, 200); } } }
</pre><pre name="code" class="html"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <com.zhang.customview.FuZaZiDingYi android:id="@+id/zidingyiView" android:layout_width="wrap_content" android:layout_height="100dp" android:layout_margin="20dp" android:padding="20dp" android:background="#000000" android:text="@string/hello_world" /> </RelativeLayout>
package com.zhang.customview; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }