自定义组件+如何让自定义Layout截取Touch事件

我自定义了一个组件,如下布局。

本文链接:http://blog.csdn.net/xzongyuan/article/details/39478023

这个自定义组件是根据上一篇转载的日志实现的,其功能是点击图标,可以把Button隐藏。而且整个FlowView空间可以被拖动,在屏幕最上层显示。这里用了View.GONE的办法,隐藏后,很干净,只剩下ImageButton了。不过这时出现一个新问题:Touch事件被传递到ImageButton了,导致RelativeLayout的onTouchEvent不能调用,这样,我无法拖动这个ImageButton了。

如何让自定义RelativeLayout拦截点击事件?办法就是调用ImageButton的setClickable(false);让子View获取不到事件,这样,父Layout就可以出发onTouchEvent()了,这时,在MotionEvent.ACTION_UP事件里,把事件传递给ImageButton

mBtnImg.setClickable(true);
mBtnImg.performClick();




public class FlowViewLayout extends RelativeLayout{ 
	
	private float mTouchX; 
	private float mTouchY; 
	private float x; 
	private float y; 
	private float mStartX; 
	private float mStartY; 
	private OnClickListener mClickListener; 
	Context mContext;
	
	static Button mBtnVC;
	static Button mBtnKeyUp;
	static Button mBtnKeyDown;
	static Button mBtnVolUp;
	static Button mBtnVolDown;
	static Button mBtnAutoConn; 
	static Button mBtnExit; 
	static ImageButton mBtnImg; 
	
	static boolean visibled = false;
	
	OnButtonClick mOnClick= new OnButtonClick();
	 
	static final String TAG = "FlowViewLayout";
	InputStream mInput;
	OutputStream mOutput;
	

	final static int RENEW = 1;
	final static int DATA_LENGTH= 2;
	final static int SOCKET_IS_OFF=3;
	final static int SEND_FAILD=4;


	final static byte[] VOICE_CANCLE = {1};
	final static byte[] KEY_UP = {2};
	final static byte[] KEY_DOWN = {3};
	final static byte[] VOL_UP = {4};
	final static byte[] VOL_DOWN = {5};

	private WindowManager.LayoutParams mWindowManagerParams;

	
	public FlowViewLayout(Context context) {
		super(context);
		   LayoutInflater.from(context).inflate(R.layout.flow_view, this, true);  
		   createLayoutView();
		   setOnClickListener(mOnClick);
	}


	
	public void setWindowManagerParams(WindowManager.LayoutParams pWMParams){
		mWindowManagerParams = pWMParams;
	}
	
	 
 
	
	public void createLayoutView(){

		//this.setAlpha(0x0);
		mBtnVC = (Button)findViewById(R.id.btnVC);
		mBtnKeyUp = (Button)findViewById(R.id.btnKeyUp);
		mBtnKeyDown = (Button)findViewById(R.id.btnKeyDown);
		mBtnVolUp = (Button)findViewById(R.id.btnVolUp);
		mBtnVolDown = (Button)findViewById(R.id.btnVolDown);
		mBtnExit = (Button)findViewById(R.id.btnFvExit);
		mBtnImg = (ImageButton)findViewById(R.id.btnImg);
		mBtnImg.setClickable(false);
	
		
		mBtnVC.setOnClickListener(mOnClick);
		mBtnKeyUp.setOnClickListener(mOnClick);
		mBtnKeyDown.setOnClickListener(mOnClick);
		mBtnVolUp.setOnClickListener(mOnClick);
		mBtnVolDown.setOnClickListener(mOnClick);
		mBtnImg.setOnClickListener(mOnClick);
		mBtnExit.setOnClickListener(mOnClick);
		
		mBtnVC.setVisibility(GONE);
		mBtnKeyUp.setVisibility(GONE);
		mBtnKeyDown.setVisibility(GONE);
		mBtnVolUp.setVisibility(GONE);
		mBtnVolDown.setVisibility(GONE);
		mBtnExit.setVisibility(GONE);
		
		getOutputStream();
		
		
	}
	
	
	private void getOutputStream() {
		
		if(BTSPPActivity.PlaceholderFragment.mBTSocket==null){

			Log.e("FlowViewLayout", "no Socke connected");
			return;
		}
		
		try {
		 	
			mOutput = BTSPPActivity.PlaceholderFragment.mBTSocket.getOutputStream();
		} catch (IOException e) {
		
			if(mOutput!=null){
				try {
					mOutput.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}
	}


	public class OnButtonClick implements View.OnClickListener{
		

		@Override
		public void onClick(View v) {
			
			if(mOutput==null){
				Log.e("FlowViewLayout", "can get the outputstream");
				return;
			}

			switch(v.getId()){
			 
			case R.id.btnVC: 
				try {
					mOutput.write(VOICE_CANCLE);
				} catch (IOException e) {
					//mUIHandler.sendEmptyMessage(SEND_FAILD);
					e.printStackTrace();
				}
			break;
			
			case R.id.btnKeyDown:
				try {
					mOutput.write(KEY_DOWN);
				} catch (IOException e) {
					//mUIHandler.sendEmptyMessage(SEND_FAILD);
					e.printStackTrace();
				}
			break;
			
			case R.id.btnKeyUp:
				try {
					mOutput.write(KEY_UP);
				} catch (IOException e) {
					//mUIHandler.sendEmptyMessage(SEND_FAILD);
					e.printStackTrace();
				}
			break;
			
			case R.id.btnVolDown:
				try {
					mOutput.write(VOL_DOWN);
				} catch (IOException e) {
					//mUIHandler.sendEmptyMessage(SEND_FAILD);
					e.printStackTrace();
				}
			break;
			
			case R.id.btnVolUp:
				try {
					mOutput.write(VOL_UP);
				} catch (IOException e) {
					//mUIHandler.sendEmptyMessage(SEND_FAILD);
					e.printStackTrace();
				}
			break;
						
			case R.id.btnImg:
				 
					if(visibled==false){
						setChildVisible();
					} else{
						setChildInvisible();
					}
			 
	
			break;
			
			case R.id.btnFvExit:
				Log.e("FlowViewLayout", "Exit");
				((BTSPPActivity)mContext.getApplicationContext()).finish();
			break;
						
			default:
			break;
			}
		}
	}
	
	public void setChildInvisible(){

		visibled=false;	
		mBtnImg.setClickable(false);
		mBtnVC.setVisibility(GONE);
		mBtnKeyUp.setVisibility(GONE);
		mBtnKeyDown.setVisibility(GONE);
		mBtnVolUp.setVisibility(GONE);
		mBtnVolDown.setVisibility(GONE);
		mBtnExit.setVisibility(GONE);
	}
	
	public void setChildVisible(){

		visibled=true;
		mBtnImg.setClickable(true);
		mBtnVC.setVisibility(VISIBLE);
		mBtnKeyUp.setVisibility(VISIBLE);
		mBtnKeyDown.setVisibility(VISIBLE);
		mBtnVolUp.setVisibility(VISIBLE);
		mBtnVolDown.setVisibility(VISIBLE);
		mBtnExit.setVisibility(VISIBLE);
	}


	
	@Override 
	public boolean onTouchEvent(MotionEvent event) { 
		//获取到状态栏的高度 
		Rect frame = new Rect(); 
		getWindowVisibleDisplayFrame(frame); 
		int statusBarHeight = frame.top; 
		System.out.println("statusBarHeight:"+statusBarHeight); 
		// 获取相对屏幕的坐标,即以屏幕左上角为原点 
		x = event.getRawX(); 
		y = event.getRawY() - statusBarHeight; // statusBarHeight是系统状态栏的高度 
		//Log.i("tag", "currX" + x + "====currY" + y); 
		switch (event.getAction()) { 
		case MotionEvent.ACTION_DOWN: // 捕获手指触摸按下动作 
			// 获取相对View的坐标,即以此View左上角为原点 
			mTouchX = event.getX(); 
			mTouchY = event.getY(); 
			mStartX = x; 
			mStartY = y; 
			//Log.i("tag", "startX" + mTouchX + "====startY" + mTouchY); 
		break; 
		
		case MotionEvent.ACTION_MOVE: // 捕获手指触摸移动动作 
			updateViewPosition(); 
		break; 
		
		case MotionEvent.ACTION_UP: // 捕获手指触摸离开动作 
			updateViewPosition(); 

			//Log.e("FlowView","out of updataViewPosition");
			
			if((x-mStartX<5) && (y-mStartY<5)){ 
			
				if(visibled==false){
	<span style="white-space:pre">				</span>//不使用事件传递,而是直接让Button响应。
<span style="white-space:pre">					</span>mBtnImg.performClick();
				}
			}
			mTouchX = mTouchY = 0; 
		break; 
		} 
		return true; 
	} 
	
	//外部调用,设置OnClickListener
	@Override 
	public void setOnClickListener(OnClickListener l) { 
		this.mClickListener = l; 
	} 
	
	
	private void updateViewPosition() { 
	// 更新浮动窗口位置参数 
		//Log.e(TAG,"in updataViewPosition");
		mWindowManagerParams.x = (int) (x - mTouchX); 
		mWindowManagerParams.y = (int) (y - mTouchY); 
		WindowManagerData.getWindowManager().updateViewLayout(this, mWindowManagerParams); // 刷新显示 
	} 

	
} 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值