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 控件底部离容器顶部的距离  

 

源码下载

下一篇博客重点说自定义控件。

 下下篇博客重点说性能优化。

转载于:https://www.cnblogs.com/yukino/p/4438415.html

android 可移动控件 /** * 用于判断view的移动 * @param view * @param event * @return */ @Override public boolean onTouch(View view, MotionEvent event) { final int X = (int) event.getRawX(); final int Y = (int) event.getRawY(); switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: if(lParams.leftMargin<0){//判断控件是否半隐藏状态 lParams.leftMargin = 0; }else if(lParams.topMargin<0){ lParams.topMargin=0; }else if(X -_xDelta> screenWidth - width){ lParams.leftMargin = screenWidth-width; } _xDelta = X - lParams.leftMargin; _yDelta = Y - lParams.topMargin; StartX = X; StartY = Y; // Log.e(TAG,"_xDelta "+_xDelta+" _yDelta "+_yDelta+" lParams.rightMargin "+lParams.rightMargin); break; case MotionEvent.ACTION_UP: //关键部分:移动距离较小,视为onclick点击行为 if (Math.abs(X - StartX) < 1.5 && Math.abs(Y - StartY) < 1.5){//计算器弹出 //这放点击后的逻辑代码 } break; case MotionEvent.ACTION_POINTER_DOWN: break; case MotionEvent.ACTION_POINTER_UP: break; case MotionEvent.ACTION_MOVE: // RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view // .getLayoutParams(); if(X - _xDelta<0 - width/2){ lParams.leftMargin = 0- width/2; }else if(X -_xDelta> screenWidth - width/2){ lParams.leftMargin = screenWidth - width/2; }else{ lParams.leftMargin = X - _xDelta; } if(Y - _yDelta<0 - height/2){ lParams.topMargin = 0 - height/2; }else if(Y -_yDelta > screenHeight - height-NavigationBarheight){ lParams.topMargin = screenHeight - height-NavigationBarheight; }else{ lParams.topMargin = Y - _yDelta; } lParams.rightMargin = -250; lParams.bottomMargin = -250; view.setLayoutParams(lParams); break; } background.invalidate(); return true; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值