当前位置:首页 » 安卓系统 » androidview事件

androidview事件

发布时间: 2022-08-14 19:46:34

㈠ android 自定义view滑动和点击事件冲突怎么解决

在Android中,对一个View同时调用OnTouch事件和OnClick事件时,导致事件冲突,比如onClick事件打算执行A动作,OnTouch事件打算执行B动作,但是在实际使用时会发现,当调用OnTouch时,有可能会同时执行A,B两个动作,这是因为OnClick事件本身就是在OnTouch事件中发生的;在onTouch事件中,如果返回true,就不会执行onClick,返回false,就同时执行onClick方法,要想把OnTouch和onClick事件完全的区分。可能过下列方法,解决该冲突问题:
就是在 OnTouch中的MotionEvent.ACTION_DOWN 时,记录下点(X1,Y1),
在 MotionEvent.ACTION_UP 时,记录下点(X2,Y2),然后比对 俩点之间的距离,如果小于一个较小数值(比如5),就认为是Click事件,onTouch中返回false,如果距离较大,可以当作onTouch事件去处理,返回true:
示范如下:
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
x1 = event.getX();
y1 = event.getY();
}
if (event.getAction() == MotionEvent.ACTION_UP) {
x2 = event.getX();
y2 = event.getY();
if (Math.abs(x1 - x2) < 6) {
return false;// 距离较小,当作click事件来处理
}
if(Math.abs(x1 - x2) >60){ // 真正的onTouch事件
}
}
return true;// 返回true,不执行click事件
}

㈡ android怎么用代码让一个view执行点击事件

view.setOnClickListener(new View.OnClickListener() {//视图设置一个点击事件的监听器
@Override
public void onClick(View v) {//重写点击事件的回调方法
//在这里添加点击后要执行的代码
}
});

㈢ android中的View是做什么的

View类是Android的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展。在游戏开发中叶可以自定义视图(View),这个画布的功能更能满足我们在游戏开发中的需要。在Android中,任何一个View类都只需重写onDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本形式等。

游戏中最重要的就是需要与玩家交互,比如键盘输入、触笔点击事件,我们如何来处理这些事件呢?Android中提供了 onKeyUp、onKeyDown、onKeyMultiple、onKeyPreIme、onTouchEvent、onTrackballEvent等方法,可以轻松地处理游戏中的事件信息。所以,在继承View时,需要重载这几个方法,当有按键按下或弹起等事件时,按键代码自动会传输给这些相应的方法来处理。

游戏的核心是不断地绘图和刷新界面,图我们已经通过onDraw 方法绘制了,下面来分析如何刷新界面。Android中提供了 invalidate 方法来实现界面刷新,注意,invalidate 不能直接在线程中调用, 就是不可以在子线程中调用明白乎?因为它违背了 Android的单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI 线程中执行,因此Android中最常用的方法就是利用Handler来实现UI线程的更新。 其实用 AsyncTask 也可以。

㈣ Android中怎么去判断点击事件中的View

每一个View都有一个Id(R.id.viewId)、在你onclick(View v)这个方法中、v既是你点击对象的view、但是怎么去判断是不是你点击的那个view就直接可以由v.getId() == R.id.viewId来判断是否为点击事件的view

㈤ 谁可以解释下,android事件分发为什么要设计成从根view到子view,而不是从子vie

Android事件传递流程在网上可以找到很多资料,FrameWork层输入事件和消费事件,可以参考:
Touch事件派发过程详解
这篇blog阐述了底层是如何处理屏幕输,并往上传递的。Touch事件传递到Activity的DecorView时,往下走就是ViewGroup和子View之间的事件传递,可以参考郭神的这两篇博客
Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
Android事件分发机制完全解析,带你从源码的角度彻底理解(下)
郭神的两篇博客清楚明白地说明了View之间事件传递的大方向,但是具体的一些晦暗的细节阐述较少,本文主要是总结这两篇博客的同时,侧重于两点:
事件分发过程中一些细节到底如何实现的?
子view到底如何和父View抢事件,父View又是如何拦截事件不发送给子View,以及如果我们需要处理这种混乱的关系才能让两者和谐相处?。
MotionEvent抽象
要明白View的事件传递,很有必要先说一下Touch事件是如何在Android系统中抽象的,这主要使用的就是MotionEvent。这个类经历了几次重大的修改,一次是在2.x版本支持多点触摸,一次是4.x将大部分代码甩给native层处理。
一次简单的事件
我们先举个栗子来说明一次完整的事件,用户触屏 滑动 到手机离开屏幕,这认为是一次完整动作序列(movement traces)。一个动作序列中包含很多动作Action,比如在用户按下时,会封装一个MotionEvent,分发给视图树,我们可以通过motionevent.getAction拿到这个动作是ACTION_DOWN。同样,在手指抬起时,我们可以接收到Action类型是Action_UP的MotionEvent。对于滑动(MOVE)这个操作,Android为了从效率出发,会将多个MOVE动作打包到一个MotionEvent中。通过getX getY可以获取当前的坐标,如果要访问打包的缓存数据,可以通过getHistorical**()函数来获取。
加入多点触摸
对于单点的操作来看,MotionEvent显得比较简单,但是考虑引入多点触摸呢?我们定义一个接触点为(Pointer)。每一个触摸点Pointer都会有一个当次动作序列的唯一Id和Index.MotionEvent中多个手指的操作API大部分都是通过pointerindex来进行的,如:获取不同Pointer的触碰位置,getX(int pointerIndex);获取PointerId等等。大部分情况下,pointerid == pointeridex。
我们从onTouch接受到一个MotionEvent,怎么拿到多个触碰点的信息?为了解开笔者刚开始学习这部分知识时的困惑,我们首先树立起一种概念:一个MotionEvent只允许有一个Action(动作),而且这个Action会包含触发这次Action的触碰点信息,对于MOVE操作来说,一定是当前所有触碰点都在动。只有ACTION_POINTER_DOWN这类事件事件会在Action里面指定是哪一个POINTER按下。
在MotionEvent的底层实现中,是通过一个16位来存储Action和Pointer信息(PointerIndex)。低8位表示Action,理论上可以表示255种动作类型;高8位表示触发这个Action的PointerIndex,理论上Android最多可以支持255点同时触摸,但是在上层代码使用的时候,默认多点最多存在32个,不然事件在分发的时候会有问题。
ACTION_DOWN OR ACTION_POINTER_DOWN:
这两个按下操作的区别是ACTION_DOWN是一个系列动作的开始,而ACTION_POINTER_DOWN是在一个系列动作中间有另外一个触碰点触碰到屏幕。
这部分详细的描述,请参考:
android触控,先了解MotionEvent
到这里,铺垫终于结束了,我们开始直奔主题。
View的事件传递
Android的Touch事件传递到Activity顶层的DecorView(一个FrameLayout)之后,会通过ViewGroup一层层往视图树的上面传递,最终将事件传递给实际接收的View。下面给出一些重要的方法。如果你对这个流程比较熟悉的话,可以跳过这里,直接进入第二部分。
dispatchTouchEvent
事件传递到一个ViewGroup上面时,会调用dispatchTouchEvent。代码有删减
public boolean dispatchTouchEvent(MotionEvent ev) {

boolean handled = false;
if (onFilterTouchEventForSecurity(ev)) {
final int action = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;

// Attention 1 :在按下时候清除一些状态
if (actionMasked == MotionEvent.ACTION_DOWN) {
cancelAndClearTouchTargets(ev);
//注意这个方法
resetTouchState();
}

// Attention 2:检查是否需要拦截
final boolean intercepted;
//如果刚刚按下 或者 已经有子View来处理
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
} else {
// 不是一个动作序列的开始 同时也没有子View来处理,直接拦截
intercepted = true;
}

//事件没有取消 同时没有被当前ViewGroup拦截,去找是否有子View接盘
if (!canceled && !intercepted) {
//如果这是一系列动作的开始 或者有一个新的Pointer按下 我们需要去找能够处理这个Pointer的子View
if (actionMasked == MotionEvent.ACTION_DOWN
|| (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
final int actionIndex = ev.getActionIndex(); // always 0 for down

//上面说的触碰点32的限制就是这里导致
final int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex)
: TouchTarget.ALL_POINTER_IDS;

final int childrenCount = mChildrenCount;
if (newTouchTarget == null && childrenCount != 0) {
final float x = ev.getX(actionIndex);
final float y = ev.getY(actionIndex);

//对当前ViewGroup的所有子View进行排序,在上层的放在开始
final ArrayList<View> preorderedList = buildOrderedChildList();
final boolean customOrder = preorderedList == null
&& isChildrenDrawingOrderEnabled();
final View[] children = mChildren;
for (int i = childrenCount - 1; i >= 0; i--) {
final int childIndex = customOrder
? getChildDrawingOrder(childrenCount, i) : i;
final View child = (preorderedList == null)
? children[childIndex] : preorderedList.get(childIndex);

// canViewReceivePointerEvents visible的View都可以接受事件
// isTransformedTouchPointInView 计算是否落在点击区域上
if (!canViewReceivePointerEvents(child)
|| !isTransformedTouchPointInView(x, y, child, null)) {
ev.setTargetAccessibilityFocus(false);
continue;
}

//能够处理这个Pointer的View是否已经处理之前的Pointer,那么把
newTouchTarget = getTouchTarget(child);
if (newTouchTarget != null) {
// Child is already receiving touch within its bounds.
// Give it the new pointer in addition to the ones it is handling.
newTouchTarget.pointerIdBits |= idBitsToAssign;
break;
} }
//Attention 3 : 直接发给子View
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
// Child wants to receive touch within its bounds.
mLastTouchDownTime = ev.getDownTime();
if (preorderedList != null) {
// childIndex points into presorted list, find original index
for (int j = 0; j < childrenCount; j++) {
if (children[childIndex] == mChildren[j]) {
mLastTouchDownIndex = j;
break;
}
}
} else {
mLastTouchDownIndex = childIndex;
}
mLastTouchDownX = ev.getX();
mLastTouchDownY = ev.getY();
newTouchTarget = addTouchTarget(child, idBitsToAssign);
= true;
break;
}

}
}

}
}

// 前面已经找到了接收事件的子View,如果为NULL,表示没有子View来接手,当前ViewGroup需要来处理
if (mFirstTouchTarget == null) {
// ViewGroup处理
handled = dispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POINTER_IDS);
} else {

if() {
//ignore some code
if (dispatchTransformedTouchEvent(ev, cancelChild,
target.child, target.pointerIdBits)) {
handled = true;
}
}

}
return handled;
}

上面代码中的Attention在后面部分将会涉及,重点注意。
这里需要指出一点的是,一系列动作中的不同Pointer可以分配给不同的View去响应。ViewGroup会维护一个PointerId和处理View的列表TouchTarget,一个TouchTarget代表一个可以处理Pointer的子View,当然一个View可以处理多个Pointer,比如两根手指都在某一个子View区域。TouchTarget内部使用一个int来存储它能处理的PointerId,一个int32位,这也就是上层为啥最多只能允许同时最多32点触碰。
看一下Attention 3 处的代码,我们经常说view的dispatchTouchEvent如果返回false,那么它就不能系列动作后面的动作,这是为啥呢?因为Attention 3处如果返回false,那么它不会被记录到TouchTarget中,ViewGroup认为你没有能力处理这个事件。
这里可以看到,ViewGroup真正处理事件是在dispatchTransformedTouchEvent里面,跟进去看看:
dispatchTransformedTouchEvent
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
View child, int desiredPointerIdBits) {

//没有子类处理,那么交给viewgroup处理
if (child == null) {
handled = super.dispatchTouchEvent(transformedEvent);
} else {
final float offsetX = mScrollX - child.mLeft;
final float offsetY = mScrollY - child.mTop;
transformedEvent.offsetLocation(offsetX, offsetY);
if (! child.hasIdentityMatrix()) {
transformedEvent.transform(child.getInverseMatrix());
}

handled = child.dispatchTouchEvent(transformedEvent);
}
return handled;
}

可以看到这里不管怎么样,都会调用View的dispatchTouchEvent,这是真正处理这一次点击事件的地方。
dispatchTouchEvent
public boolean dispatchTouchEvent(MotionEvent event) {
if (onFilterTouchEventForSecurity(event)) {
//先走View的onTouch事件,如果onTouch返回True
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}

if (!result && onTouchEvent(event)) {
result = true;
}
}
return result;
}

我们给View设置的onTouch事件处在一个较高的优先级,如果onTouch执行返回true,那么就不会去走view的onTouchEvent,而我们一些点击事件都是在onTouchEvent中处理的,这也是为什么onTouch中返回true,view的点击相关事件不会被处理。

㈥ android 判断view是否有设置了点击事件

在对一个VIEW注册单击事件监听后,onTouchEvent中是无法接收到该VIEW中的DOWN事件的,这其中有着一个事件传递的过程,介意你可以去查下,提供你一个解决方法:你可以使用setOnTouchListener来处理这个ImageView的点击事件,OnTouchListener里面的方法onTouch是有返回值的,返回true则说明已处理完毕不会再继续传递这个事件;返回false则说明未处理完毕需要继续传递这个事件,按你现在的问题,你应当返回false。

㈦ android 如何获取一个界面最顶层的view并处理单击事件的分发机制

android事件分发机制 就是一个触摸事件发生了,从一个窗口传递到一个视图,再传递到另外一个视图,最后被消费的过程,在android中还是比较复杂的传递流程如下:

(1) 事件从Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截,从最上层的View(ViewGroup)开始一直往下(子View)传递。子View可以通过onTouchEvent()对事件进行处理。

(2) 事件由父View(ViewGroup)传递给子View,ViewGroup可以通过onInterceptTouchEvent()对事件做拦截,停止其往下传递。

㈧ 如何监听android view的生命周期

android view有以下14个周期:
1、onFinishInflate() 当View中所有的子控件均被映射成xml后触发 。
2、onMeasure( int , int ) 确定所有子元素的大小 。
3、onLayout( boolean , int , int , int , int ) 当View分配所有的子元素的大小和位置时触发 。
4、onSizeChanged( int , int , int , int ) 当view的大小发生变化时触发 。
5、onDraw(Canvas) view渲染内容的细节。
6、onKeyDown( int , KeyEvent) 有按键按下后触发 。
7、onKeyUp( int , KeyEvent) 有按键按下后弹起时触发 。
8、onTrackballEvent(MotionEvent) 轨迹球事件 。
9、onTouchEvent(MotionEvent) 触屏事件 。
10、onFocusChanged( boolean , int , Rect) 当View获取或失去焦点时触发 。
11、onWindowFocusChanged( boolean ) 当窗口包含的view获取或失去焦点时触发 。
12、onAttachedToWindow() 当view被附着到一个窗口时触发 。
13、onDetachedFromWindow() 当view离开附着的窗口时触发,Android123提示该方法和 onAttachedToWindow() 是相反的。
14、onWindowVisibilityChanged( int ) 当窗口中包含的可见的view发生变化时触发。

㈨ android view 内的imageview 设置 点击事件

1、
iv.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Log.d("dd", "123");
}
});

2、图片的id是项目自动生成的
在的值在R.java文件里面
你可以把你要显示的图片的id放到一个数据里面
int image_id = {R.id.imageView1,R.id.imageView2,....};
然后通过数据的位置
访问id为imageView5的即
v.findViewByid(image_id[4]);

热点内容
诺基亚密码忘了打什么电话 发布:2024-09-17 03:27:09 浏览:555
树深度优先算法 发布:2024-09-17 03:26:58 浏览:472
跳转页源码 发布:2024-09-17 03:13:05 浏览:543
html文件上传表单 发布:2024-09-17 03:08:02 浏览:784
聊天软件编程 发布:2024-09-17 03:00:07 浏览:726
linuxoracle安装路径 发布:2024-09-17 01:57:29 浏览:688
两个安卓手机照片怎么同步 发布:2024-09-17 01:51:53 浏览:207
cf编译后没有黑框跳出来 发布:2024-09-17 01:46:54 浏览:249
安卓怎么禁用应用读取列表 发布:2024-09-17 01:46:45 浏览:524
win10设密码在哪里 发布:2024-09-17 01:33:32 浏览:662