在手機屏幕上能夠實現的人機交互行為,大致包括點擊按鈕,拉動滑動塊,物體縮放,上下左右拉動等。
手機屏幕觸摸事件的監聽方法:
1.首先要設置一塊布局區域,frameLayout/LinearLayout等都可以,並為布局設置id;
2.在Activity中聲明相應的布局類型,並通過findViewById()方法找到該布局,然后為該布局區域設置setOnTouchListener()方法,就能監聽在相應屏幕觸摸操作
實現屏幕觸摸事件監聽的代碼:
private LinearLayout Land;
Land = (LinearLayout) findViewById(R.id.Land); Land.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) {
// event是當手指觸摸到屏幕后,新建的對象,里面封裝了一系列對屏幕的操作信息 switch(event.getAction()){ case MotionEvent.ACTION_DOWN: //當手指第一次按下的時候,執行的操作 break; case MotionEvent.ACTION_UP: //當手指抬起,離開屏幕的時候,執行的操作 break;
case MotionEvent.ACTION_MOVE:
//當手指一直按在屏幕上,並且移動的時候執行的操作
break;
} //這里設置為true表示一直監聽這塊區域的觸摸行為,false則表示監聽一次就不再監聽 return true; } });
判斷上下左右操作行為的方法:
在設置了setOnTouchListener()方法后,里面傳進來的event中包含了所有手指對屏幕的操作信息,我們通過對event的解讀,判斷具體的操作行為。
具體的實現代碼:
private float X1;
private float X2;
private float Y1; private float Y2; private float ComparedX; private float ComparedY; private LinearLayout Land; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Land = (LinearLayout) findViewById(R.id.Land); Land.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN: X1 = event.getX(); //獲取剛按下屏幕位置的X坐標的值 Y1 = event.getY(); //獲取剛按下屏幕位置的Y坐標的值 break; case MotionEvent.ACTION_UP: X2 = event.getX(); //當手指抬起時,再次獲取屏幕位置的X值 Y2 = event.getY(); //同理 Action(X1,X2,Y1,Y2); break; } //設置一直監聽此區域的觸摸事件 return true; } }); } public void Action(float X1, float X2, float Y1, float Y2){ ComparedX = X2 - X1; //第二次的X坐標的位置減去第一次X坐標的位置,代表X坐標上的變化情況 ComparedY = Y2 -Y1; //同理
//當X坐標的變化量的絕對值大於Y坐標的變化量的絕對值,以X坐標的變化情況作為判斷依據
//上下左右的判斷,都在一條直線上,但手指的操作不可能划直線,所有選擇變化量大的方向上的量
//作為判斷依據
if (Math.abs(ComparedX) >= Math.abs(ComparedY)){ //leader X if (ComparedX>0){
//手機屏幕的坐標值,從左上方到右下方增加,橫為X軸,豎為Y軸
Toast.makeText(MainActivity.this,"向右滑動",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(getApplicationContext(),"向左滑動",Toast.LENGTH_SHORT).show(); } }else{ // leader Y if (ComparedY>0){ Toast.makeText(getApplicationContext(),"向下滑動",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(getApplicationContext(),"向上滑動",Toast.LENGTH_SHORT).show(); } } }
縮放操作的實現:
識別上下左右的拉動操作,只需要監聽一個手指的操作情況,但要實現縮放的識別需要監聽兩個手指。
但監聽兩個手指的操作行為,並不需要操作和補充監聽的函數,因為event中包含了所有屏幕收到的操作信息,我們只需要更加細致的解讀event就能實現縮放的判斷。
縮放的具體實現代碼:
Touch.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE:
//在手指一直放在屏幕上的動作中設置縮放操作,則縮放的操作是漸變的
if (event.getPointerCount()>=2){ //獲取一共幾個觸摸點,只有當觸摸的點大於等於兩個,才判斷縮放行為
//event中封存了所有屏幕被觸摸的點的信息,第一個觸摸的位置可以通過event.getX(0)/getY(0)得到
float offSetX = event.getX(0) - event.getX(1); float offSetY = event.getY(0) - event.getY(1); //運用三角函數的公式,通過計算X,Y坐標的差值,計算兩點間的距離 currentdistance = (float) Math.sqrt(offSetX*offSetX+offSetY*offSetY); if (lastDistance < 0){//如果是第一次進行判斷 lastDistance = currentdistance; }else{
//之所以大於10才執行,是為了給出一個緩沖時間,設置一個變化讀取的閥值
//否則會出現手指放在上面不動,而被操作的圖片卻一直在不斷的放大縮小的情況 if (currentdistance-lastDistance>10){ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) iv.getLayoutParams(); //這里必須要使用這種寫法,否則屏幕的寬度和長度返回的是指int數據,而1.1為float型
//直接計算,會拋棄小數部分,導致毫無變化
//若是有其他方法能使得int和float數據之間順利計算,也是可以的
lp.width= (int) (1.1f*iv.getWidth()); lp.height= (int) (1.1f*iv.getHeight());
//安卓中設計參數的修改和設定,都是通過parameters的屬性來實現 iv.setLayoutParams(lp); Log.e(Tag,"fangda"); }else if (lastDistance-currentdistance>10){ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) iv.getLayoutParams(); lp.width= (int) (0.9f*iv.getWidth()); lp.height= (int) (0.9f*iv.getHeight()); iv.setLayoutParams(lp); Log.e(Tag,"suoxiao"); } } //在一次縮放操作完成后,將本次的距離賦值給lastDistance,以便下一次判斷
//但這種方法寫在move動作中,意味着手指一直沒有抬起,監控兩手指之間的變化距離超過10
//就執行縮放操作,不是在兩次點擊之間的距離變化來判斷縮放操作
//故這種將本次距離留待下一次判斷的方法,不能在兩次點擊之間使用
lastDistance = currentdistance; } break; } return true; } });