下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么在Android中捕获点击事件范围
今天就跟大家聊聊有关怎么在Android中捕获点击事件范围,可能很多人都不太了解,为了让大家更加了解,在下给大家总结了以下内容,希望大家根据这篇文章可以有所收获。View的Tween动画过程中点击事件的位置并不会因为动画位置的改变而改变,是因为在动画过程中layout的位置实际上没有变,因此曾经一度认为View的点击事件(其实不仅仅是点击事件,包括所有的触摸事件)触发的范围是该View在layout的时候指定的left,top,right,bottom。今天才发现不完全是这样的。一切都是因为平时看代码没有仔细一点所造成了对问题理解不全面。在这里记录一下发现问题到处理问题的过程。自定义这样一个ViewGroup,layout两个线性布局,左边的LinearLayout覆盖全屏幕,右面的LinearLayout在屏幕外面隐藏。然后观察在想做滑动的过程中,第二个LinearLayout显示出来的过程中,按钮Button和第二个线性布局的位置信息:可以看到,在向左滑第二个线性布显示出来的过程中,他的位置并没有变,这里指的是通过getLeft(),getTop(),getRight(),getBottom()获得的位置,也就是由layout决定的位置。既然位置并没有改变,那么这时候点击第二个线性布局和按钮点击事件也被响应了,就说明捕获点击事件的位置并不完全是在layout的位置。因为并没有将手伸到屏幕外面去点击…回头来看ViewGroup#dispatchTouchEvent方法在分发触摸事件的时候:for
(int
i
=
count
-
1;
i
>=
0;
i--)
{
final
View
child
=
children[i];
if
((child.mViewFlags
&
VISIBILITY_MASK)
==
VISIBLE
||
child.getAnimation()
!=
null)
{
child.getHitRect(frame);
if
(frame.contains(scrolledXInt,
scrolledYInt))
{
//
offset
the
event
to
the
view's
coordinate
system
final
float
xc
=
scrolledXFloat
-
child.mLeft;
final
float
yc
=
scrolledYFloat
-
child.mTop;
ev.setLocation(xc,
yc);
child.mPrivateFlags
&=
~CANCEL_NEXT_UP_EVENT;
if
(child.dispatchTouchEvent(ev))
{
//
Event
handled,
we
have
a
target
now.
mMotionTarget
=
child;
return
true;
}
}
}其中frame.contains(scrolledXInt,scrolledYInt)函数就是判断点(scrolledXInt,scrolledYInt)是不是在frame矩形里面。这个矩形frame是由child.getHitRect(frame);获得的:public
void
getHitRect(Rect
outRect)
{
outRect.set(mLeft,
mTop,
mRight,
mBottom);
}显然这个矩形就是由该子View的Layout的布局参数所决定的。但是scrolledXInt和scrolledYInt参数,并不是我们手指点击的位置:final
int
action
=
ev.getAction();
final
float
xf
=
ev.getX();
final
float
yf
=
ev.getY();
final
float
scrolledXFloat
=
xf
+
mScrollX;
final
float
scrolledYFloat
=
yf
+
mScrollY;
……
final
int
scrolledXInt
=
(int)
scrolledXFloat;
final
int
scrolledYInt
=
(int)
scrolledYFloat;可以看出,在判断这个点是否包含在子View内的时候,这个点不是手指所点击的坐标,而是手指点击的坐标加上了mScrollX和mScrollY,然后在判断是否在该子View的范围里面。现在思考向左滑动的过程中,虽然第二个线性布局的位置没有变,还是layout的参数位置,是:mLeft:720,mTop:0,mRight:1440,mBottom:1134。但是他的父View的mScrollX改变了,向左滑mScrollX大于0,这是用手点击第二个线性布局,手所点击的位置再加上mScrollX的值,这时就会落在了第二个线性布局的layout的范围里面。
测试代码:自定义MyViewGroup:public
class
MyViewGroup
extends
ViewGroup
{
public
static
final
String
TAG
=
"MyViewGroup";
private
int
childCount;
private
GestureDetector
detector;
private
Button
btn;
private
LinearLayout
ll2;
public
MyViewGroup(Context
context,
AttributeSet
attrs,
int
defStyle)
{
super(context,
attrs,
defStyle);
init(context);
}
public
MyViewGroup(Context
context,
AttributeSet
attrs)
{
super(context,
attrs);
init(context);
}
public
MyViewGroup(Context
context)
{
super(context);
init(context);
}
private
void
init(final
Context
context)
{
detector
=
new
GestureDetector(context,
new
MyOnGestureListener());
LinearLayout
ll1
=
new
LinearLayout(context);
ll1.setBackgroundColor(Color.BLUE);
ll2
=
new
LinearLayout(context);
ll2.setBackgroundColor(Color.RED);
btn
=
new
Button(context);
btn.setText("点击按钮");
ll2.addView(btn);
addView(ll1);
addView(ll2);
setOnTouchListener(new
MyTouchEvent());
ll2.setOnClickListener(new
OnClickListener()
{
@Override
public
void
onClick(View
v)
{
Toast.makeText(context,
"点击了线性布局2",
0).show();
}
});
btn.setOnClickListener(new
OnClickListener()
{
@Override
public
void
onClick(View
v)
{
Toast.makeText(context,
"点击了Button",
0).show();
}
});
}
@Override
protected
void
onMeasure(int
widthMeasureSpec,
int
heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec,
heightMeasureSpec);
childCount
=
getChildCount();
for
(int
i
=
0;
i
<
childCount;
i++)
{
View
child
=
getChildAt(i);
child.measure(widthMeasureSpec,heightMeasureSpec);
}
}
@Override
protected
void
onLayout(boolean
changed,
int
l,
int
t,
int
r,
int
b)
{
for
(int
i
=
0;
i
<
childCount;
i++)
{
View
child
=
getChildAt(i);
child.layout(0+i*getWidth(),
0,
(i+1)*getWidth(),
getHeight());
}
}
private
class
MyTouchEvent
implements
View.OnTouchListener{
@Override
public
boolean
onTouch(View
v,
MotionEvent
event)
{
detector.onTouchEvent(event);
return
true;
}
}
private
class
MyOnGestureListener
extends
SimpleOnGestureListener{
@Override
public
boolean
onScroll(MotionEvent
e1,
MotionEvent
e2,
float
distanceX,
float
distanceY)
{
scrollBy((int)
distanceX,
0);
if
(getScrollX()%
10
==
0)
{
Log.i(TAG,
"Button左上右下位置:"
+
btn.getLeft()
+
"/"
+
btn.getTop()
+
"/"
+
btn.getRight()
+
"/"
+
btn.getBottom());
Log.i(TAG,
"线性布局2的左上右下位置:"
+
ll2.getLeft()
+
"/"
+
ll2.getTop()
+
"/"
+
ll2.getRight()
+
"/"
+
ll2.getBottom());
Log.i(TAG,
"MyViewGroup的mScrollX:"
+
getScrollX());
}
return
super.onScroll(e1,
e2,
distanceX,
distanceY);
}
}
}然后在Activity里面:public
class
MainAc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 家政服务协议全套
- 中考语文复习现代小说名篇
- 安全生产月事故案例分析
- 四川烟草系统招聘考试专卖法练习题
- 抖音直播陪跑协议模板
- 战略管理试题及答案
- 食品储存管理制度(2篇)
- GBT 2889.1-2008 滑动轴承 术语、定义和分类 第1部分:设计、轴承材料及其性能
- DL-T 1998-2019 感应滤波变压器成套设备使用技术条件
- 液压与气压传动 课件 3.2齿轮泵
- 烟草车辆运输方案
- 湘教版七年级美术下册4《扮靓生活的花卉纹样》精品课件(共22张PPT)
- 微机原理 寻址方式与基本指令实验
- 华为性格测试攻略
- 扶壁式挡土墙计算表格(excel)
- 小学生心理健康教育ppt课件.ppt
- 讲义 儿童身高促进PPT课件.ppt
- 生物制品的发展.ppt
- 煤矿回收设备安全技术措施
- 酒歌教学反思
- 《论人民民主专政》读书笔记.doc
评论
0/150
提交评论