Android View动画运行时,在运动的View上绑定的事件将不能被触发,因为诸如点击事件等,触发点是绑定在View控件初始化时所在位置的点击,当动画移动后点击坐标就发生了改变,通过查询一些资料,了解到,Android 3.0以下,动画存在问题,它只移动了View绘制显示的地方,却没有移动View的物理位置,具体底层实现大家可以看源代码了解,我不大清楚底层,这里就不多说了,下面说说简单的解决方法。
只需继承父级布局,覆盖onTouchEvent(或者其他需要捕获的事件)。这里我以FrameLayout为例,因为要捕获点击事件,实现onTouchEvent,然后通过获取当前点击坐标计算出当前点击范围内包含的View控件,找到第一个就直接触发该View的事件,然后break,示例代码如下:
public class ExtendFrameLayout extends FrameLayout { public ExtendFrameLayout(Context context) { super(context); } public ExtendFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); } public ExtendFrameLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: float x = event.getX(); float y = event.getY(); for(int i=0;i < getchildcount();i++){ View child = getChildAt(i); if(child!=null){ if (containPoint(child, x, y)) { Toast.makeText(getContext(), "Touch->"+x+":"+y, Toast.LENGTH_SHORT).show(); child.performClick(); break; } } } } return super.onTouchEvent(event); } private boolean containPoint(View view, float x, float y) { Transformation trans = new Transformation(); Animation anim = view.getAnimation(); if(anim!=null){ anim.getTransformation(view.getDrawingTime(), trans); } Matrix matrix = trans.getMatrix(); int dx = view.getLeft(); int dy = view.getTop(); x -= dx; y -= dy; Matrix mat = new Matrix(); if (matrix.invert(mat)) { float[] pointsSrc = new float[] { x, y }; float[] pointsEnd = new float[] { 0, 0 }; mat.mapPoints(pointsEnd, pointsSrc); x = pointsEnd[0] + dx; y = pointsEnd[1] + dy; } Rect rect = new Rect(); view.getHitRect(rect); return rect.contains((int) x, (int) y); } }
以上示例代码参考网上资源修改而来,仅方便初学者,另外这里只是传统的View动画,因为要兼容低版本Android设备,这里没有考虑属性动画,本人非专业Android开发人员,高手勿笑。
上一篇: 关于HTML5不得不说的一些事 下一篇: Git push error:dst refspec XXX matches more than one