首先附上文章的轉載內容的鏈接:
學習android 可拖動事件首先需要對android的屏幕和touchevent參數建立一個詳細的知識結構。
一、首先明確一下 android中的坐標系統 :屏幕的左上角是坐標系統原點(0,0),原點向右延伸是X軸正方向,原點向下延伸是Y軸正方向。
1、View的坐標
需要注意view的坐標是相對父容器而言的,包括:getTop()、getBottom(),getLeft(),getRight()。以getTop為例,函數源代碼為:
/**
* Top position of this view relative to its parent.
*相對應父控件的top位置,單位為像素,即頭部到父控件的距離
* @return The top of this view, in pixels.
*/
@ViewDebug.CapturedViewProperty
public final int getTop() {
return mTop;
}
圖示1:
圖示2:
1、視圖左側位置 view.getLeft()
2、視圖右側位置 view.getRight()
3、視圖頂部位置 view.getTop();
4、視圖底部位置 view.getBottom();
5、 視圖寬度 view.getWidth();
6、視圖高度 view.getHeight()
2、MotionEvent類中 getRowX()和 getX()
1、event.getRowX():觸摸點相對於屏幕原點的x坐標
2、event.getX(): 觸摸點相對於其所在組件原點的x坐標
二、其次需要對ontouchevent有一個明確的掌握
例如如果需要響應action_up的話,那么action_down的事件處理需要return true。(在action_up中加一些東西就相當與點擊事件了)
附上源碼並進行說明:
1、首先需要獲取屏幕寬度長度。記錄按下down時點的位置。
2、之后在move事件中不斷計算移動的位置並進行邊界檢查,然后使用layout函數設置新的坐標位置。使用postInvalidate進行刷新。
package com.example.hellotouchevent; import android.os.Bundle; import android.app.Activity; import android.util.DisplayMetrics; import android.view.Menu; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.RelativeLayout; import android.widget.Toast; public class MainActivity extends Activity implements OnTouchListener{ private RelativeLayout mRlFather; private RelativeLayout mRlMezi; private DisplayMetrics dm; private int lastX, lastY; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); dm = getResources().getDisplayMetrics(); final int screenWidth = dm.widthPixels; final int screenHeight = dm.heightPixels - 50; setListener(); } private void initView() { mRlFather = (RelativeLayout) findViewById(R.id.rl_father); mRlMezi = (RelativeLayout) findViewById(R.id.rl_mezi); } private void setListener() { mRlFather.setOnTouchListener(this); mRlMezi.setOnTouchListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onTouch(View v, MotionEvent event) { int ea = event.getAction(); final int screenWidth = dm.widthPixels; final int screenHeight = dm.heightPixels; switch(v.getId()){ case R.id.rl_father: break; case R.id.rl_mezi: switch(ea){ case MotionEvent.ACTION_DOWN: lastX = (int) event.getRawX();// 獲取觸摸事件觸摸位置的原始X坐標 lastY = (int) event.getRawY(); break; case MotionEvent.ACTION_MOVE: int dx = (int) event.getRawX() - lastX; int dy = (int) event.getRawY() - lastY; int l = v.getLeft() + dx; int b = v.getBottom() + dy; int r = v.getRight() + dx; int t = v.getTop() + dy; // 下面判斷移動是否超出屏幕 if (l < 0) { l = 0; r = l + v.getWidth(); } if (t < 0) { t = 0; b = t + v.getHeight(); } if (r > screenWidth) { r = screenWidth; l = r - v.getWidth(); } if (b > screenHeight) { b = screenHeight; t = b - v.getHeight(); } v.layout(l, t, r, b); lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); v.postInvalidate(); break; case MotionEvent.ACTION_UP: break; default: break; } default : break; } return true; } }
layout函數
btn1.layout(100, 100, 300, 300); //容器左上為0,0 // L 控件左邊離容器左邊的距離 // T 控件頂部離容器頂部的距離 // R 控件右邊離容器左邊的距離 // B 控件底部離容器頂部的距離
源碼下載:
下一篇博客重點說自定義控件。
下下篇博客重點說性能優化。