我自定义了一个组件,如下布局。
本文链接: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); // 刷新显示
}
}