android 可拖動控件 ontouchevent


首先附上文章的轉載內容的鏈接:

 

學習android 可拖動事件首先需要對android的屏幕和touchevent參數建立一個詳細的知識結構。

1、android坐標系統

 

 一、首先明確一下 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 控件底部離容器頂部的距離  

 

源碼下載

下一篇博客重點說自定義控件。

 下下篇博客重點說性能優化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM