有时候,我们使用的是普通的TextView,而非Button,有的时候也并非列表(个人习惯问题,主页的带图按钮不太喜欢做成列表,更喜欢直观一些),这时候需要按下背景变色的效果,需要使用selector来实现。此时在小米5x上出现了不论是否在控件内部都触发ACTION_UP而非ACTION_CANCEL的问题,于是采用以下方式解决:
btnNext.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_CANCEL:
btnNext.setSelected(false);
break;
case MotionEvent.ACTION_DOWN:
btnNext.setSelected(true);
break;
case MotionEvent.ACTION_UP:
//判断是否是移动到外部再抬起手指
if(isOutterUp(event,v)){
event.setAction(MotionEvent.ACTION_CANCEL);
return onTouch(v,event);
}
btnNext.setSelected(false);
click(v);
break;
}
return true;
}
private boolean isOutterUp(MotionEvent event, View v) {
float touchX = event.getX();
float touchY = event.getY();
float maxX = v.getWidth();
float maxY = v.getHeight();
return touchX<0 || touchX>maxX || touchY < 0 || touchY > maxY;
}
private void click(View v) {
//进行点击的相关操作
}
});
简单的说就是移动到控件外部再抬起的ACTION_UP当做ACTION_CANCEL进行处理。下图表示了超出边界的所有情况。
当然,可以集成一个相同的listener进行处理,改装后的代码如下:
父类:
private OnTouchListener mSelectListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_CANCEL:
v.setSelected(false);
break;
case MotionEvent.ACTION_DOWN:
v.setSelected(true);
break;
case MotionEvent.ACTION_UP:
if(isOutterUp(event,v)){
event.setAction(MotionEvent.ACTION_CANCEL);
return onTouch(v,event);
}
v.setSelected(false);
v.performClick();
break;
}
return true;
}
private boolean isOutterUp(MotionEvent event, View v) {
float touchX = event.getX();
float touchY = event.getY();
float maxX = v.getWidth();
float maxY = v.getHeight();
return touchX<0 || touchX>maxX || touchY < 0 || touchY > maxY;
}
};
protected void setOnSelectListener(View v,OnClickListener mOnClickListener){
v.setOnClickListener(mOnClickListener);
v.setOnTouchListener(mSelectListener);
}
子类使用:
setOnSelectListener(drawTxtAttend, new OnClickListener() {
@Override
public void onClick(View v) {
//点击事件处理
}
});