可拖动Button
前几天在做可拖动的按钮,在网上看到很多实例,但是都是仅仅实现了按钮的拖动,一但添加按钮监听,又会出现onClick和onTouch冲突,或是事件传播机制的问题。在学习touch事件的传播机制时,注意到click事件就是touch事件的“子类”,于是想到用这个方法实现拖动的按钮,在我看到的网络上的例子上改动了下:
自定义Button类:
1 import android.content.Context; 2 import android.util.Log; 3 import android.view.MotionEvent; 4 import android.widget.Button; 5 6 public class MyButton extends Button{ 7 8 final int screenWidth; 9 final int screenHeight; 10 int CurrentX,CurrentY;//记录当前的位置 11 int flag; 12 public MyButton(Context context, int screenWidth,int screenHeight) 13 { 14 super(context); 15 this.screenWidth = screenWidth; 16 this.screenHeight = screenHeight; 17 } 18 19 @Override 20 public boolean onTouchEvent(MotionEvent event) { 21 22 super.onTouchEvent(event); 23 int ea=event.getAction(); 24 Log.i("TAG", "Touch:"+ea); 25 switch(ea) 26 { 27 case MotionEvent.ACTION_DOWN: 28 CurrentX = (int) event.getRawX(); 29 CurrentY = (int) event.getRawY(); 30 Log.i("TAG", "CurrentX:"+CurrentX+" CurrentY:"+CurrentY); 31 flag=0; 32 break; 33 34 case MotionEvent.ACTION_MOVE: 35 36 int dx =(int)event.getRawX() - CurrentX; 37 int dy =(int)event.getRawY() - CurrentY; 38 int left = this.getLeft() + dx; 39 int top = this.getTop() + dy; 40 int right = this.getRight() + dx; 41 int bottom = this.getBottom() + dy; 42 43 44 if(left < 0){ 45 left = 0; 46 right = left + this.getWidth(); 47 } 48 49 if(right > screenWidth){ 50 right = screenWidth; 51 left = right - this.getWidth(); 52 } 53 54 if(top < 0){ 55 top = 0; 56 bottom = top + this.getHeight(); 57 } 58 if(bottom > screenHeight){ 59 bottom = screenHeight; 60 top = bottom - this.getHeight(); 61 } 62 this.layout(left, top, right, bottom); 63 Log.i("", "position:" + left +", " + top + ", " + right + ", " + bottom); 64 65 CurrentX = (int) event.getRawX(); 66 CurrentY = (int) event.getRawY(); 67 flag=1; 68 break; 69 case MotionEvent.ACTION_UP: 70 if(flag==0) 71 { 72 Log.v("-MyButton-","-----点击事件------"); 73 return false; 74 } 75 else 76 { 77 Log.v("-MyButton-","-----拖动事件------"); 78 return true; 79 } 80 } 81 return true; 82 } 83 84 //定义getflag()方法,便于绑定监听 85 public int getflag() 86 { 87 return flag; 88 } 89 90 }
MainActivity:
1 import android.os.Bundle; 2 import android.app.Activity; 3 import android.util.DisplayMetrics; 4 import android.view.View; 5 import android.view.View.OnClickListener; 6 import android.widget.RelativeLayout; 7 import android.widget.Toast; 8 9 public class MainActivity extends Activity { 10 11 @Override 12 public void onCreate(Bundle savedInstanceState) 13 { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 RelativeLayout root = (RelativeLayout)findViewById(R.id.root); 17 //获得屏幕分辨率 18 DisplayMetrics dm = getResources().getDisplayMetrics(); 19 final int screenWidth = dm.widthPixels; 20 //因为标题栏和状态栏高都为25,所以要减掉50 21 final int screenHeight = dm.heightPixels - 50; 22 final MyButton mybutton = new MyButton(this,screenWidth,screenHeight); 23 mybutton.setText("试验按钮by沙发土豆"); 24 root.addView(mybutton); 25 //为mybutton设置监听 26 mybutton.setOnClickListener(new OnClickListener() { 27 28 public void onClick(View v) 29 { 30 if(mybutton.getflag()==0) 31 { 32 //在此处自定义自己的onClick功能 33 Toast.makeText(MainActivity.this, "点击事件", 3000).show(); 34 } 35 else 36 { 37 //这里实际应用的时候,直接把else语句删掉就行了 38 Toast.makeText(MainActivity.this, "拖动事件", 3000).show(); 39 } 40 } 41 }); 42 } 43 }
以上程序,touch事件会出现3种情况:
1、没有拖动,仅有ACTION_DOWN,ACTION_UP,则getflag()==0,进入“点击事件”;
2、发生拖动,有ACTION_DOWN,ACTION_MOVE和ACTION_UP,但是拖动比较缓慢,始终没有跑出Button的范围,则getflag()==1,进入“拖动事件”;
3、发生拖动,且拖动快速,跑出了Button的范围,则仅仅进入了OnTouchEvent方法,没有进入OnClickListener方法,也实现了拖动。
大家可以看看,多多指正