Android系统编程入门系列之界面Activity交互响应

Android系统编程入门系列之界面Activity交互响应,第1张

概述在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件View,不仅如此,用户的每次触摸 *** 作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图View响应。那么

在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件VIEw,不仅如此,用户的每次触摸 *** 作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图VIEw响应。那么对于用户的 *** 作,应该如何响应,而同一个 *** 作到底是作用于界面,还是界面中的某一个子视图?针对用户的 *** 作对象所产生的交互方式不同,本文将分别展开介绍。

界面内交互界面响应

说到界面交互,很容易想到用户在设备屏幕上的触摸 *** 作。可是屏幕那么大要怎么确定用户触摸的位置呢?AndroID系统定义了一套屏幕坐标规则,该规则不仅适用于当前的屏幕交互,在后文提及的动画绘制及其他屏幕相关 *** 作等都同样适用。该规则将屏幕的左上角作为屏幕坐标的原点,从左上角往右上角延伸的方向作为屏幕坐标的x轴,从左上角往左下角延伸的方向作为屏幕坐标的y轴。

比如针对一款 1024x512 尺寸的TV设备,其左下角的屏幕坐标值为 (0,512),右下角的屏幕坐标值为 (1024,512),右上角的屏幕坐标值为 (1024,0),左上角的屏幕坐标值为 (0,0)。

对屏幕的触摸位置有了衡量标准,是不是就可以根据不同的位置做触摸 *** 作了呢?说到触摸 *** 作,也需要细化之后单独处理。AndroID系统将用户 *** 作行为,大致分为三种:按下行为,滑动行为,抬起释放行为。这样系统就可以根据每一个 *** 作行为做单独的响应处理了。

另外,用户的 *** 作对象,除了上文提到的硬件设备屏幕以外,还有硬件设备的按键(包括硬件按键和虚拟按键)。只不过对按键的 *** 作行为只有按下行为和抬起释放行为两种,而且按键的 *** 作不需要用到屏幕坐标相关内容。

基于上文的介绍,可以在界面Activity中可以分别重写下边三个方法对用户的界面 *** 作交互做出响应。

boolean ontouchEvent(MotionEvent event)
在子视图没有处理的情况下,用户对硬件设备屏幕的每一个 *** 作,都会回调一次该方法。

其参数android.view.MotionEvent事件类的实例化对象event。
event.getAction()方法可以获取当前事件行为,包括MotionEvent.ACTION_DOWN按下行为、MotionEvent.ACTION_MOVE滑动行为、MotionEvent.ACTION_UP抬起释放行为等。
event.getX()方法获取当前 *** 作的屏幕坐标x轴值。
同理event.getY()方法获取当前 *** 作的屏幕坐标y轴值。

boolean onKeyDown(int keyCode,KeyEvent event)
在子视图没有处理的情况下,用户对硬件设备按键的每一次按下行为,都会回调一次该方法。

参数一int类型的keyCode指定按键类型,一般其值与参数二event.getKeyCode()相等。
参数二android.view.KeyEvent类的实例化对象event。
event.getAction()方法同样可以获取当前事件行为,只有KeyEvent.ACTION_DOWN按下行为和KeyEvent.ACTION_UP抬起释放行为两个行为值。
event.getKeyCode()方法可以获取触发当前事件的按键类型,其值包括KeyEvent.KEYCODE_HOMEHOME键,KeyEvent.KEYCODE_POWER电源键,KEYCODE_VolUME_UP音量增加键等。

boolean onKeyUp(int keyCode,KeyEvent event)
在子视图没有处理的情况下,用户对硬件设备按键的每一次抬起释放行为,都会回调一次该方法。其两个参数与上述onKeyDown()中的两个参数类似。

视图响应

相对来说,界面内的视图响应要繁琐一些,而能实现的效果也更多样化。当把视图VIEw作为用户的 *** 作对象时,仍然可以重写上述界面响应的三个方法,但是系统视图往往也封装了一层更加简单粗暴的响应方法。

在视图中重写界面响应的三个方法后,如果返回的结果为true,则上文界面响应中的三个方法将不会被回调。

对于重写界面响应中的三个方法的方式,有两种代码实现方式。一是针对已定义的视图VIEw类,通过调用类似 setontouchListener (VIEw.OntouchListener l)等监听方法,在监听类中实现相关响应方法即可。或者将已定义的视图VIEw作为父类,重新创建一个自定义视图VIEw,在新的自定义VIEw中可以直接重写相关响应方法,而在声明使用原视图VIEw类的地方,修改为使用新的自定义VIEw类。通常针对声明为final的类只能使用方式一实现。

VIEw.OntouchListener类中实现的ontouch(VIEw v,MotionEvent event)方法,会优先于视图VIEw内部的ontouchEvent(MotionEvent event)被调用,因此如果ontouch(VIEw v,MotionEvent event)返回结果为true,将不会回调视图VIEw内部的ontouchEvent(MotionEvent event),而且该视图VIEw内部的其他响应交互类监听(如setonClickListener(VIEw.OnClickListener l)、setonLongClickListener (VIEw.OnLongClickListener l)等)也不会被调用。

为什么需要封装一层响应方法呢?用户对视图的 *** 作,往往就是点击(短时间内执行按下行为和抬起释放行为),长按(在执行按下行为后等待一段时间再执行抬起释放行为),拖拽(在执行按下行为后执行一段滑动行为之后再执行抬起释放行为)这些固定 *** 作类型。如果每个视图都要细分用户的 *** 作行为,就会有大量冗余的 *** 作类型判断代码,所以AndroIDSDK定义了一系列接口分别对应用户的 *** 作类型。视图如果需要响应某个 *** 作,只需要设置其 *** 作类型接口的实例化对象,并在该对象中实现相关方法即可。而这些接口主要有以下三个。

View.OnClickListener接口
需要实现onClick(VIEw vIEw)方法,在该方法内响应响应视图VIEw被用户点击后的代码逻辑。View.OnLongClickListener接口
需要实现onLongClick(VIEw vIEw)方法,在该方法内响应响应视图VIEw被用户长按后的代码逻辑。View.OnDragListener接口
需要实现onDrag(VIEw v,DragEvent event)方法,在该方法内响应视图VIEw被用户拖拽后的代码逻辑。

另外,不同的系统视图也可能有单独设置的响应方法,或者自定义视图也会提供单独的响应方法,例如列表视图中的某一行数据被单独点击后如何响应,这些都要根据具体的视图类查找并使用对应的响应方法,这里不再赘述。

事件传递机制

在上文界面响应的三个方法中,关于他们被回调的时机,有个前提是子视图没有处理,即子视图的界面响应方法返回结果为false。这就涉及到AndroID系统的事件传递机制了。
我们知道界面Activity在创建之后会调用setContentVIEw(int layoutID)加载根视图VIEw,而根视图里边则可以内嵌一层层的子视图。那么,如果用户将手指触摸到屏幕上,会触发按下行为,该行为作为事件首先传递到根视图中,之后根视图再将该事件传递给子视图,子视图再将该事件传递给子视图的子视图,这样按照加载时的嵌套顺序一层层传递事件,称之为事件分发。
直到该事件传递到最后一层子视图,或者某一层视图不再继续传递该事件,那么该事件将在最后传递到的这层视图中被首先处理。而每层视图在收到传递进来的事件后,都有两条路可以选择,要么将该事件继续传递给子视图,要么自己处理该事件,如果选择第二条路不再继续传递子视图而是自己处理该事件,称之为事件拦截。
一旦某层视图处理了该事件,那么其父层视图将继续处理该事件,之后是父层的父层视图处理该事件,事件被这样一层层处理,直到根视图处理该事件结束,称之为事件处理。
在经历了事件分发和事件处理之后,这样的一个事件传递机制就算完成了。而上文提到的每一个事件,都是如此。

上述过程在代码中的实现,只需要针对事件分发、事件拦截和事件处理分别定义一个可重写的方法即可。能够重写该方法的位置主要是androID.app.AcitivtyandroID.vIEw.VIEw中,由于事件拦截只会发生在子视图的传递过程中,在界面中并不需要,所以事件拦截对应的方法只在androID.vIEw.GroupVIEw中重写。

boolean dispatchtouchEvent (MotionEvent event)
当某个事件被分发到该视图时,系统回调视图中的该方法。返回结果表示当前事件是否被处理。boolean onIntercepttouchEvent(MotionEvent event)
当某个事件被分发到该视图后,系统会回调视图中的该方法,根据其返回结果判断是否拦截该事件交由当前视图处理。默认返回结果为false,表示不拦截该事件,将会继续回调子视图的dispatchtouchEvent()。返回结果为true时,表示拦截该事件,将会回调当前视图的ontouchEvent().boolean ontouchEvent (MotionEvent event)
当某个事件轮到该视图被处理时,会在该视图的上述事件分发方法boolean dispatchtouchEvent (MotionEvent event)中回调到该方法。返回结果表示当前事件是否被处理。界面间交互

上文介绍了针对一个界面Activity的交互响应,那么两个界面Activity之间如何交互呢?这就用到在加载界面一文中启动Activity所使用的androID.content.Intent意图类了。不同于用户与界面的交互,界面间交互主要是变量数据的共享,所以通过Intent支持的交互数据类型是有限的。

发送数据界面

在启动一个界面Activity之前要先创建意图对象,在该意图对象调用putExtras(Bundle bundle)方法,可以将要发送的数据打包成android.os.Bundle类型的实例存入。

而该Bundle对象可以存储的数据类型支持包括booleancharbyteshortintfloatdoublelong八种基本数据类型,String类型和实现Parcelable接口的任意类型,及其[]数组或ArrayList数组,和其他一些不常用类型。这些数据都是以key-value键值对的形式保存在Bundle对象中。对于要保存的不同数据类型,分别调用对应的putT(String key,T value)系列方法即可以参数一key和参数二value的形式存入,同样可以调用对应的getT(String key)系列方法取出指定参数一key对应的value数据,这里的T泛指支持的不同数据类型。
另外也可以在创建的意图对象中直接调用putExtra(String key,T value)系列方法,将要发送的数据直接以key-value键值对的形式存入,同样也可以使用getTExtra(String key)系列方法取出指定参数一key对应的value数据,这里的T同样泛指Bundle可支持的不同数据类型。

在打包所有的数据后,就可以在当前界面Activity中继续调用startActivity(Intent intent)系列方法启动Intent意图参数中指定的另一界面Activity了。
这里的startActivity(Intent)方法是最简单的启动方法,另外还有startActivity(Intent,Bundle)在启动时将要发送的数据打包作为参数二传入。
或者startActivityForResult(Intent intent,int requestCode)在启动时传入一个唯一值作为参数二,以区分启动不同界面的意图,在启动的界面Activity返回后,系统会调用当前界面Activity中的onActivityResult(int requestCode,int resultCode,Intent data)方法,因此可以重写该方法。并根据参数一的唯一性对之前启动的不同界面意图做区分处理。参数二是根据启动界面不同关闭状态所返回的结果值,默认为androID.app.Activity.RESulT_CANCELED,另外也可以为androID.app.Activity.RESulT_FirsT_USERandroID.app.Activity.RESulT_OK,其值需要在启动界面返回时设置。参数三是从启动界面返回的Intent类型,主要使用其中的Bundle打包数据类型对象,同样其值可以在启动界面返回时设置。

接收数据界面

作为接收数据的启动界面Activity,在其绑定上下文环境之后,一般是在onCreate(Bundle savedInstanceState)方法中,可以使用getIntent()方法获取传递进来的Intent意图对象,获取该对象之后自然就可以通过getBExtras()或一系列getTExtra(String key)获取到打包的数据,这样在启动界面中就可以使用在启动之前上一个界面Activtiy中的变量数据了。

而当启动界面Activity在被用户 *** 作返回时,系统将回调该启动界面的onBackpressed()方法,之后将该Activity从栈中移出并销毁。所以可以重写onBackpressed()方法,在该方法中调用setResult(int resultCode,Intent data)设置上文提到的返回时参数。
或者在启动界面Activity代码中也可以主动调用finish()方法,以关闭当前界面。因此在调用finish()方法之前先调用setResult(int resultCode,Intent data)设置返回参数即可。

总结

以上是内存溢出为你收集整理的Android系统编程入门系列之界面Activity交互响应全部内容,希望文章能够帮你解决Android系统编程入门系列之界面Activity交互响应所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1119341.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存