自定义控件—在布局中点击自己响应操作,点击别处,隐藏自己

今天遇到一个需求,一个gone的布局,在显示出来的时候,点击自己,响应触摸事件,点击到别的地方,把自己隐藏起来,

分析起来其实很简单,就是点击自己的时候不拦截点击事件的分发,不点击自己的时候拦截分发,隐藏自己,主要是需要知道自己在什么时候被点击了。

这是一个大布局(根布局),集成的线性布局。主要需要设置好setObserverViewsetAffectView。  一个就是要响应点击事件的控件,一个是它的父布局。

getDescendantCoordRelativeToSelf()这个方法算出了布局的矩形位置,eventInLocation(MotionEvent ev)  这个方法判断点击释放在矩形框内,这要就可以知道什么时候需要分发点击事件。  如此来控制布局的显示、隐藏、响应。
public class CustomLinearLayout extends LinearLayout {

private View mObserverView;

private View mAffectView;

private Rect mRect;

private boolean mInit = false;

public CustomLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}

public void setObserverView(View view) {
mObserverView = view;
}
public void setAffectView(View view){
mAffectView = view;
}

private void calculate() {
int[] locations = new int[2];
getDescendantCoordRelativeToSelf(mObserverView, locations);
mRect = new Rect(locations[0], locations[1],
locations[0] + mObserverView.getMeasuredWidth(),
locations[1] + mObserverView.getMeasuredHeight());
}

private float getDescendantCoordRelativeToSelf(View descendant, int[] coord) {
float scale = 1.0f;
float[] pt = {coord[0], coord[1]};
descendant.getMatrix().mapPoints(pt);
scale *= descendant.getScaleX();
pt[0] += descendant.getLeft();
pt[1] += descendant.getTop();
ViewParent viewParent = descendant.getParent();
while (viewParent instanceof View && viewParent != this) {
final View view = (View) viewParent;
view.getMatrix().mapPoints(pt);
scale *= view.getScaleX();
pt[0] += view.getLeft() - view.getScrollX();
pt[1] += view.getTop() - view.getScrollY();
viewParent = view.getParent();
}
coord[0] = Math.round(pt[0]);
coord[1] = Math.round(pt[1]);
return scale;
}


@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if(mObserverView == null){
return false;
}
if (!mInit) {
calculate();
mInit = true;
}
if (isViewShow()) {
if (eventInLocation(ev)) {
return false;
} else {
mAffectView.setVisibility(View.GONE);
return true;
}
}
return super.onInterceptTouchEvent(ev);
}

private boolean isViewShow() {
return mAffectView.getVisibility() == View.VISIBLE;
}

private boolean eventInLocation(MotionEvent ev) {
int x = (int) ev.getX();
int y = (int) ev.getY();
return mRect.contains(x, y);
}
}
posted @ 2017-09-11 10:08  wlwqnj  阅读(419)  评论(0编辑  收藏  举报