Android自定义View
Android的显示控件都是继承自View,当我们开发的时候Android官方的View达不到我们想要的效果时就可以选择自定义Viwe,这也是Java的面向对象给我们带来的便利。
View的自定义其实就是继承Android SDK中官方的View控件,再加入自己编写的逻辑、显示元素最终达到想要的显示效果。在日常的开发中一般的需求都可以使用Android SDK官方的显示View达到。但是一些特殊的显示需求官方的View无法到达所需求的效果时就可以考虑自定义View或使用第三方自定义View的插件
创建一个自定义的View首先我们要先创建一个继承系统View的Java类
package com.arvin.customview
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
public class customView extends View{
// 自定义View需要添加构造方法
// 主要在代码中使用的
public customView (Context context) {
super(context);
}
// 在xml布局中使用的
public customView (Context context, AttributeSet attr) {
super(context, attr);
}
}
在定义的View中可以通过View的 onDraw() 方法绘制文字、图片等我们想要的信息
protected void onDraw(Canvas canvas) {
Paint paint = new Patint();
paint.setTextSize(30);
// 绘制文字通过paint指定的大小
canvas.drawText("this is onDraw", 0, 30, paint);
// 绘制直线
canvas.drawLine(0, 60, 100, 60, paint);
// 通过坐标绘制矩形
canvas.drawRect(0, 90, 100, 190, paint);
// 通过Rect对象绘制矩形
Rect rect = new Rect(0, 90, 100, 190);
canvas.drawRect(rect, paint);
// 通过RectF绘制矩形
RectF rectf = new RectF(0, 90, 100, 190);
canvas.drawRect(rectf, paint);
// 绘制圆角矩形
canvas.drawRoundRect(rect, 10, 10, paint);
// 绘制圆形
canvas.drawCircle(50, 270, 50, paint);
// 绘制Bitmap
Bitmap bitmap = BiatmapFactory.decodeResource(getResource(),
R.drawable.ic_launcher);
canvas.drawBitmap(bitmap, 0, 350, paint);
}
加入逻辑处理进行绘图操作:
@Override
protected void onDraw(Canvas canvas) {
paint.setTextSize(30);
paint.setColor(0xfff91121);
canvas.drawText("自定义View", rx, 30, paint);
rectF = new RectF(left, 60, right, 160);
if (left < 90) {
canvas.drawCircle(110, 110, 10, paint);
}
canvas.drawArc(rectF, startAngle, sweepAngle, true, paint);
if (myThread == null) {
myThread = new MyThread();
myThread.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
while (true) {
rx += 3;
if (rx > getWidth()) {
rx = 0 - paint.measureText("自定义View");
}
if (flag) {
startAngle = 0;
sweepAngle = 360;
flag = false;
} else {
startAngle = 30;
sweepAngle = 300;
flag = true;
}
left += 3;
right += 3;
if (left > getWidth()) {
left = -100;
right = 0;
}
postInvalidate();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
对自定义View的封装与代码简化:
将自定义的View做成抽象类,在抽象类中只关心线程与对外提供可供外部实现的抽象方法
package com.arvin.customview.v2;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
public abstract class BaseView extends View {
private MyThread myThread;
public BaseView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BaseView(Context context) {
super(context);
}
protected abstract void darwSub(Canvas canvas);
protected abstract void Logic();
@Override
protected final void onDraw(Canvas canvas) {
if (myThread == null) {
myThread = new MyThread();
myThread.start();
} else {
darwSub(canvas);
}
}
class MyThread extends Thread {
@Override
public void run() {
while (true) {
Logic();
postInvalidate();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
自定义View的逻辑处理:
在逻辑处理的类中只关心绘制与逻辑功能处理,而不用去关心线程的启动等
package com.arvin.customview.v2;
import com.arvin.customview.v2.BaseView.MyThread;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
public class LogicView extends BaseView{
private float rx = 0;
private Paint paint = new Paint();
private float startAngle = 0;
private float sweepAngle = 0;
private boolean flag = false;
private float right = 100, left = 0;
private RectF rectF;
public LogicView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LogicView(Context context) {
super(context);
}
@Override
public void darwSub(Canvas canvas) {
paint.setTextSize(30);
paint.setColor(0xfff91121);
canvas.drawText("自定义View", rx, 30, paint);
rectF = new RectF(left, 60, right, 160);
if (left < 90) {
canvas.drawCircle(110, 110, 10, paint);
}
canvas.drawArc(rectF, startAngle, sweepAngle, true, paint);
}
@Override
public void Logic() {
rx += 3;
if (rx > getWidth()) {
rx = 0 - paint.measureText("自定义View");
}
if (flag) {
startAngle = 0;
sweepAngle = 360;
flag = false;
} else {
startAngle = 30;
sweepAngle = 300;
flag = true;
}
left += 3;
right += 3;
if (left > getWidth()) {
left = -100;
right = 0;
}
}
}