随着要求增多,原生态的控件有时候已经不能知足需求了,如今就开始简单学习自定义控件,先自定义一个TextViewjava
首先,定义一个类继承 View类,以下写android
public class MyView extends View{ }
由于父类已经定义了一个有参的构造函数,此时编译器不会为你调用默认的构造函数,canvas
当子类继承时,必须在本身的构造函数显式调用父类的构造函数,本身才能确保子类在初始化前父类会被实例化,app
若是你父类中有无参的构造函数,子类就不会强制要求调用,即你写的那个就能够经过,编译器会默认帮你调用父类的构造函数。ide
那咱们就默认第一个继承父类的Context函数
public class MyView extends View{ public MyView(Context context) { super(context); } }
如今布局MyView有了,怎么显示出来呢?固然直接new一个出来了布局
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); //这是默认布局 //改为咱们定义的布局 new一个出来 setContentView(new MyView(this)); }
运行后学习
发现一个空白布局,咱们自定义的第一个控件已经成功了,不过太空白好像很差,加点色彩吧,继承系统的绘画方法,加点绿色而后画个圆,如今重写MyView字体
public class MyView extends View{ private Paint mPaint;// 画笔 public MyView(Context context) { super(context); // TODO Auto-generated constructor stub initPaint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GREEN); //画布设为绿色 //画笔 画了一个圆 canvas.drawCircle(MeasureUtil.getScreenSize((Activity) mContext)[0] / 2, MeasureUtil.getScreenSize((Activity) mContext)[1] / 2, 200, mPaint); } /** * 初始化画笔 */ private void initPaint() { // 实例化画笔并打开抗锯齿 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); /* * 设置画笔样式为描边,圆环嘛……固然不能填充否则就么意思了 * * 画笔样式分三种: * 1.Paint.Style.STROKE:描边 * 2.Paint.Style.FILL_AND_STROKE:描边并填充 * 3.Paint.Style.FILL:填充 */ mPaint.setStyle(Paint.Style.FILL); // 设置画笔颜色为自定义颜色 mPaint.setColor(Color.argb(255, 255, 128, 103)); /* * 设置描边的粗细,单位:像素px 注意:当setStrokeWidth(0)的时候描边宽度并不为0而是只占一个像素 */ mPaint.setStrokeWidth(10); } } public final static class MeasureUtil { /** * 获取屏幕尺寸 */ public static int[] getScreenSize(Activity activity) { DisplayMetrics metrics = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); return new int[] { metrics.widthPixels, metrics.heightPixels }; } }
如今从新运行一下this
好了,手动建立第一个view成功了,但是这个view是占满整个屏幕的,并且在xml中使用会报错,如何编写一个能够自定义大小的而且能够在xml中使用的view呢?还记得View父类提供了3个构造函数,没错第二就提供了控件大小的属性 AttributeSet attrs控件属性 咱们就重写MyView,实现能够自定义大小
public class MyView extends View{ //实现 能够设置自定义布局大小 public MyView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); canvas.drawColor(Color.GREEN); } }
activity_main的xml布局
<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" > <com.MyView android:layout_width="match_parent" android:layout_height="80dp" /> </RelativeLayout>
从新运行
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }
成功了高度80,如今加上一些别的属性 作个TextView吧。
public class MyView extends View{ private Paint mPaint;// 画笔 private String text; //显示文字 private float textSize; //文字字体大小 private int textColor; //文字字体颜色 private int backColor; //背景颜色 public MyView(Context context, AttributeSet attrs) { super(context,attrs); //得到 资源布局得到数据 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyView); textColor = array.getColor(R.styleable.MyView_textColor, 0XFF00FF00); //提供默认值,放置未指定 textSize = array.getDimension(R.styleable.MyView_textSize, 36); text = (String) array.getText(R.styleable.MyView_text); backColor = array.getColor(R.styleable.MyView_backgroudColor, 0XFF00FF00); array.recycle(); //要释放 initPaint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(backColor); //背景 //显示文字 canvas.drawText(text, 10, 110, mPaint); } private void initPaint() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(textColor); mPaint.setTextSize(textSize); mPaint.setStrokeWidth(10); } }
属性配置文件 attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyView"> <attr name="textSize" format="dimension" /> <attr name="textColor" format="color" /> <attr name="backgroudColor" format="color" /> <attr name="text" format="string" /> </declare-styleable> </resources>
主布局
xmlns:app1=" //注册本身写的属性值 <com.myview.MyView android:id="@+id/vi" app1:text="hello" app1:textSize="20sp" app1:textColor="#0000ff" app1:backgroudColor="#ffff00" android:layout_width="100dp" android:layout_height="150dp" />
好了本身写的TextView已经成功了