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) ;
}
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。