View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等。
其实View的使用很简单--extends View即可,该重写重写。比较常用的有绘图函数onDraw();按键按下事件函数onKeyDown();按键抬起事件函数onKeyUp();触屏事件函数onTouchEvent()。
OnDraw()的使用:
假使现在我们来画一个“Hello”文本,我们就可以用到上面的绘图函数onDraw(Canvas canvas)。
既然要画东西那么我们首先得有只笔把,那就是Paint。画笔可以是各种颜色的,我们可以通过Paint.setColor()来挑个带颜色的笔。
现在我们已经有了一只带颜色的笔,要画东西的话还得有样必不可少的东西那就是画布--Canvas。因为Canvas对象是由绘图函数onDraw()直接传递进来的,那么我们现在只要canvas.drawText()就可以画文本了。
代码如下:
protected void onDraw(Canvas canvas)
{
//创建画笔
Paint mPaint = new Paint() ;
//设置画笔颜色
mPaint.setColor(Color.BLUE) ;
//绘制文本
canvas.drawText("Hello", 200, 200, mPaint) ;
super.onDraw(canvas) ;
}
Canvas的drawText函数中有四个参数,第一个便是要显示的字符串,第二个和第三个是文本绘制在屏幕的具体位置即X、Y轴坐标。第四个便是我们的画笔Paint。
关于X、Y轴坐标需要知道的是手机屏幕不管是横屏显示,还是竖屏显示,手机的最左上角永远是(0,0)坐标;而且手机屏幕的(0,0)坐标水平向右永远是X轴正方向,(0,0)坐标垂直向下永远是Y轴的正方向。
我们的View定义完毕之后如何应用这个View到Activity上呢,还记得Activity中onCreate()函数下的setContentView()函数吗,只要实例化我们的View,并且作为参数传入就可以了。代码如下:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState) ;
this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去除界面标题
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置Activity界面充满屏幕
setContentView(new MyView(mContext)) ;
}
事件监听
按键监听事件:
按键按下事件函数onKeyDown();
按键抬起事件函数onKeyUp();
触屏监听事件:
触屏事件函数onTouchEvent();
触屏事件函数可以在用户手指按下时、手指离开屏幕时、手指在屏幕中滑动时触发。
假使我们想让刚才画的文本跟随手指进行滑动则可以在onTouchEvent()中获取到当前手指的坐标,然后传递到Canvas.drawText() 的坐标上,代码如下:
@Override
publicbooleanonTouchEvent(MotionEvent event)
{
Log.d(log, "onTouchEvent event.getAction:" + event.getAction()) ;
float x = event.getX() ;
float y = event.getY() ;
if(event.getAction() == MotionEvent.ACTION_MOVE){
Log.d(log,"MotionEvent.ACTION_MOVE");
textX = x;
textY = y;
}elseif(event.getAction() == MotionEvent.ACTION_DOWN){
Log.d(log,"MotionEvent.ACTION_DOWN");
textX = x;
textY = y;
}elseif (event.getAction() == MotionEvent.ACTION_UP){
Log.d(log,"MotionEvent.ACTION_UP");
textX = x;
textY = y;
}
invalidate();
returntrue ;
}
需要注意的是,invalidate()这个函数,通过此函数可以实现重新绘制画布,就相当于重新调用了onDraw()函数。因为onDraw()函数只有在View试图一开始创建的时候会执行一遍,所以在onTouchEvent()中重新绘制画布便可实现我们想要的效果了。
另外View类中除了invalidate()函数,还有一个名为postInvalidate()函数,它们的主要区别是:invalidate()不能在当前子线程中循环调用执行,即该函数只能在UI主线程中使用;而postInvalidate()便可以在子函数中循环执行。所以如果只在主线程中用这两个函数的话是都可以使用的。
大致View的使用就是这样,下面附件有个实现点击任意两个点使其连接成线的demo。
publicclass MyView extends View
{
private String log = "MyView" ;
floattextX = 20 ;
floattextY = 20 ;
floatlastX = 0 ;
floatlastY = 0 ;
ArrayList < Float > lineX = new ArrayList < Float >() ;
ArrayList < Float > lineY = new ArrayList < Float >() ;
public MyView ( Context context )
{
super(context) ;
setFocusable(true) ;
// TODO Auto-generated constructor stub
}
@Override
publicboolean onKeyDown(int keyCode, KeyEvent event)
{
Log.d(log, "onKeyDown") ;
returnsuper.onKeyDown(keyCode, event) ;
}
@Override
publicboolean onKeyUp(int keyCode, KeyEvent event)
{
Log.d(log, "onKeyUp") ;
// TODO Auto-generated method stub
returnsuper.onKeyUp(keyCode, event) ;
}
@Override
publicboolean onTouchEvent(MotionEvent event)
{
Log.d(log, "onTouchEvent event.getAction:" + event.getAction()) ;
/**实现拖动文本**/
/*float x = event.getX() ;
float y = event.getY() ;
if(event.getAction() == MotionEvent.ACTION_MOVE){
Log.d(log,"MotionEvent.ACTION_MOVE");
textX = x;
textY = y;
}else if(event.getAction() == MotionEvent.ACTION_DOWN){
Log.d(log,"MotionEvent.ACTION_DOWN");
textX = x;
textY = y;
}else if (event.getAction() == MotionEvent.ACTION_UP){
Log.d(log,"MotionEvent.ACTION_UP");
textX = x;
textY = y;
}
invalidate();*/
/**实现任意两点连接成线**/
switch ( event.getAction() )
{
case KeyEvent.ACTION_DOWN :
Log.d(log, "onTouchEvent ACTION_DOWN") ;
lastX = textX ;
lastY = textY ;
float x = event.getX() ;
float y = event.getY() ;
lineX.add(x) ;
lineY.add(y) ;
textX = x ;
textY = y ;
break ;
case KeyEvent.ACTION_UP :
Log.d(log, "onTouchEvent ACTION_UP") ;
float x1 = event.getX() ;
float y1 = event.getY() ;
textX = x1 ;
textY = y1 ;
break ;
case KeyEvent.ACTION_MULTIPLE :
Log.d(log, "onTouchEvent ACTION_MULTIPLE") ;
float x2 = event.getX() ;
float y2 = event.getY() ;
textX = x2 ;
textY = y2 ;
break ;
default :
break ;
};
invalidate();
returntrue ;
}
/**
* 绘图函数
* */
@Override
protectedvoid onDraw(Canvas canvas)
{
Log.d(log, "onDraw") ;
/**实现任意两点连接成线**/
if (lineX == null)
{
lineX = new ArrayList < Float >() ;
}
if (lineY == null)
{
lineY = new ArrayList < Float >() ;
}
if (lineX.size() > 1 && lineY.size() > 1)
{
for ( int i = 0 ; i < lineX.size() ; i++ )
{
if (i <= lineX.size() - 2)
{
// 创建画笔
Paint mPaint = new Paint() ;
mPaint.setColor(Color.BLUE) ;
canvas.drawLine(lineX.get(i), lineY.get(i), lineX.get(i + 1), lineY.get(i + 1), mPaint) ;
}
}
}
/**实现拖动文本**/
// 创建画笔
/* Paint mPaint = new Paint() ;
mPaint.setColor(Color.BLUE) ;
canvas.drawText("Hello", textX, textY, mPaint) ;
*/
super.onDraw(canvas) ;
}
}