Android自定義view實現(xiàn)拖動小球移動
Android應(yīng)用界面中可以看得見的都是由一個個的View所組成的,幾乎所有的可視的控件都是基于View寫的。在View中提供了對touch也就是手勢的捕獲和傳遞,我們可以對View里面手勢的重寫來達(dá)到我們所需要的特性。比如說我們現(xiàn)在要做一款游戲,內(nèi)容很簡單,就是要實現(xiàn)讓如圖所示的一個黑色的小球在根據(jù)手指移動而在手機屏幕內(nèi)移動。

我們可以重寫View里面的public boolean onTouchEvent(MotionEvent event)方法,來獲取到所有的手勢操作,再從中選擇出所需要的手勢進行操作。
所以可以得到如下的一段代碼:
/**
* Created by obo on 15/8/21.
*/
public class TouchView extends View{
public static String TAG = TouchView.class.getCanonicalName();
//當(dāng)前小球的位置
private PointF currrentPosition = new PointF(100,100);
//手指觸摸起點坐標(biāo)
private PointF moveStartPosition = new PointF(0,0);
//當(dāng)前手指位置坐標(biāo)
private PointF moveEndPosition = new PointF(0,0);
private Context context;
public TouchView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawCircle(currrentPosition.x + (moveEndPosition.x - moveStartPosition.x),currrentPosition.y+(moveEndPosition.y - moveStartPosition.y),50,new Paint());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
moveStartPosition.x = event.getX();
moveStartPosition.y = event.getY();
break;
case MotionEvent.ACTION_MOVE:
moveEndPosition.x = event.getX();
moveEndPosition.y = event.getY();
//刷新
this.postInvalidate();
break;
case MotionEvent.ACTION_UP:
currrentPosition.x += (moveEndPosition.x - moveStartPosition.x);
currrentPosition.y += (moveEndPosition.y - moveStartPosition.y);
moveStartPosition.x = moveEndPosition.x;
moveStartPosition.y = moveEndPosition.y;
break;
default:
}
return true;
}
}
可以看到當(dāng)前onTouchEvent方法返回ture,表明這個View是要對當(dāng)前手勢操作進行捕獲的,這里包括 按下、移動和抬起等相關(guān)操作,如果返回的是false的話,只會接收到第一次的一個ACTION_DOWN也就是按下的響應(yīng),之后的移動手勢和抬起的手勢都無法獲取到。
方法onTouchEvent里面做了三件事情:1.當(dāng)用戶手指按下的時候,初始化記錄下開始按下的坐標(biāo),并立即返回不需要刷新界面。2.當(dāng)用戶移動手指的時候,記錄用戶手指的位置,并且重新刷新界面。3.當(dāng)用戶退出手勢也就是抬起手指的時候,將位移賦值給基礎(chǔ)坐標(biāo)點,并讓手勢起點坐標(biāo)和手勢終點坐標(biāo)x、y相等(清零)。
而如果使用Matrix的話將會使整個過程變得更加簡單,只需要事先得到小球的bitmap就能使用matrix對小球進行包括 位移、形變、旋轉(zhuǎn)在內(nèi)的變換,這里只使用matrix的位移變換效果,具體實現(xiàn)代碼如下:
/**
* Created by obo on 15/8/26.
*/
public class MatrixView extends View {
public final static String TAG = MatrixView.class.getCanonicalName();
//bitmap運行矩陣
Matrix matrix = new Matrix();
//記錄點
PointF startPoint = new PointF();
//自定義bitmap
Bitmap bitmap = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);
public MatrixView(Context context, AttributeSet attrs) {
super(context, attrs);
Canvas canvas = new Canvas(bitmap);
//直接在bitmap上面繪制一個小球
canvas.drawCircle(50,50,50,new Paint());
}
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawBitmap(bitmap, matrix, new Paint());
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
super.onTouchEvent(event);
if (event.getActionMasked() == MotionEvent.ACTION_MOVE)
{
matrix.postTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y );
//刷新
this.postInvalidate();
}
startPoint.x = event.getX();
startPoint.y = event.getY();
return true;
}
}
這一塊的代碼實現(xiàn)的效果和先前的一樣,增加了Matrix變量,少了一個PointF變量,同時在onTouchEvent和onDraw方法中的代碼量也降低了一些。Matrix其實是一個3X3的矩陣,使用Matrix可以一步步積累變換的操作,無論對matrix操作多少次,其對圖片的處理復(fù)雜度都是固定不變的,并且能對圖片進行快速的變換,這就是使用matrix的帶來的好處。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
淺談Android Studio導(dǎo)出javadoc文檔操作及問題的解決
這篇文章主要介紹了淺談Android Studio導(dǎo)出javadoc文檔操作及問題的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Android 6.0開發(fā)實現(xiàn)關(guān)機菜單添加重啟按鈕的方法
這篇文章主要介紹了Android 6.0開發(fā)實現(xiàn)關(guān)機菜單添加重啟按鈕的方法,涉及Android6.0針對相關(guān)源碼的修改與功能添加操作技巧,需要的朋友可以參考下2017-09-09
android studio 新手入門教程(二)項目的導(dǎo)入教程圖解
這篇文章主要介紹了android studio 新手入門教程(二)項目的導(dǎo)入教程圖解,需要的朋友可以參考下2017-12-12
android 仿微信demo——微信主界面實現(xiàn)
本系列文章主要介紹了微信小程序-閱讀小程序?qū)嵗╠emo),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望能給你們提供幫助2021-06-06
Android自定義Gallery控件實現(xiàn)3D圖片瀏覽器
這篇文章主要介紹了Android自定義Gallery控件實現(xiàn)3D圖片瀏覽器,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
Android實現(xiàn)收到新短信后自動發(fā)郵件功能
這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)收到新短信后自動發(fā)郵件功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05

