触摸[2] 拖动

来源:互联网 发布:弱视网络训练软件 编辑:程序博客网 时间:2024/05/18 17:25

【参考链接】

 

以如下应用场景为例,在FrameLayout中有一个MyTextView,当手指在MyTextView上触摸时,MyTextView随着手指而移动。

主要是事件处理结合《View的长宽及其在父ViewGroup中的位置,如何改变?》中的方法来使用

 

此外,如果该View设置了onClickListener,则在手指离开屏幕ACTION_UP以后还会触发onClickListener

如果希望发生拖动时不触发onClick,可以增加一个变量来控制

 

public classMyTextViewextendsTextView {

   
private intlastX;
    private int
lastY;

    private boolean
callOnClick=true;

    public
MyTextView(Context context) {
       
super(context);
        
init();
   
}

   
publicMyTextView(Context context,AttributeSet attrs) {
       
super(context,attrs);
       
init();
   
}

   
publicMyTextView(Context context,AttributeSet attrs, intdefStyleAttr) {
       
super(context,attrs,defStyleAttr);
       
init();
   
}

   
private voidinit(){
       setOnClickListener(
newOnClickListener() {
           
@Override
           
public voidonClick(View v) {
               
if(callOnClick)
                   Toast.makeText(getContext()
,"onClick!",Toast.LENGTH_SHORT).show();
           
}
       })
;
   
}

   
@Override
   
public booleanonTouchEvent(MotionEvent event) {
       
super.onTouchEvent(event);//for onClick/onLongClick

       
switch(event.getAction()){
           
caseMotionEvent.ACTION_DOWN:
               
lastX=(int) event.getRawX();
               
lastY= (int) event.getRawY();

               
callOnClick=true;
               break;

           case
MotionEvent.ACTION_MOVE:
               
intnewX= (int) event.getRawX();
               int
newY= (int) event.getRawY();

               int
deltaX=newX-lastX;
               int
deltaY=newY-lastY;

               
//这里就不加了,不然拖动的断断续续
//               int touchSlop=ViewConfiguration.get(this.getContext()).getScaledTouchSlop();
//               if(Math.abs(deltaX)>touchSlop || Math.abs(deltaY)>touchSlop){

                   //
因为这个例子中FrameLayout里面只有这个MyTextView,所以可以用setLayoutParams()实现效果
                   //
并且不要求改变大小,所以也可以用layout()实现
//                   FrameLayout.LayoutParamsparams=(FrameLayout.LayoutParams)this.getLayoutParams();
//                   params.leftMargin+=deltaX;
//                   params.topMargin+=deltaY;
//                   setLayoutParams(params);
//                   requestLayout();

                    
layout(getLeft()+deltaX,getTop()+deltaY,getRight()+deltaX,getBottom()+deltaY);

                   
//更新坐标
                   
lastX=newX;
                   
lastY=newY;
//               }

               
callOnClick=false;
               break;

           case
MotionEvent.ACTION_UP:
           
caseMotionEvent.ACTION_CANCEL:
               
lastX=(int) event.getRawX();
               
lastY= (int) event.getRawY();

               
callOnClick=true;
               break;

           default
:
               
break;
       
}
       
return true;
   
}
}