最近碰到需求需要实现GridView空白处的点击事件,记录一下:
这次也需要我们定义一个类去继承GridView,先上代码在解释
public class UnscrollableGridView extends GridView {
private OnTouchBlankListener OnTouchBlankListener;
public UnscrollableGridView(Context context) {
super(context);
}
public UnscrollableGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public UnscrollableGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
//定义回调接口
public interface OnTouchBlankListener {
void OnTouchBlank();
}
//设置空白处点击事件方法
public void setOnTouchBlankListener(OnTouchBlankListener listener) {
OnTouchBlankListener = listener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (OnTouchBlankListener != null) {
//这句很关键,是获取用户点击是第几个子项还是空白处
int motionPosition = pointToPosition((int) event.getX(), (int) event.getY());
//当用户点击是空白处时并抬起手指时,执行回调方法
if (motionPosition == INVALID_POSITION && event.getAction() == MotionEvent.ACTION_UP) {
OnTouchBlankListener.OnTouchBlank();
return true;
}
}
return super.onTouchEvent(event);
}
}
最关键就在于pointToPosition方法,看下源码
整个方法的功能是:你传入用户点击的坐标(x,y),返回你点击的第几个子项,如果点击的位置下没有子项,就返回INVALID_POSITION,我们就是通过它来判断用户点击的是空白处。
记录一个小知识点:
当你的listview或GridView的子控件中包括ImageButton,Button,CheckBox等子控件时,此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子控件,item本身的点击没有响应。
这时候就可以使用descendantFocusability来解决,该属性是定义viewGroup和其子控件两者之间获取焦点的关系。
属性的值有三种:
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点
我们用到的是第三种
同步.gif
网友评论