Android View动画进行中事件无效解决方法
2016-04-09 11:21
806 查看
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);
}
}
只需继承父级布局,覆盖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);
}
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories