志在指尖
用双手敲打未来

事件传递机制以及自定义View相关

Android的视图树
Android中View的机制主要是Activity的显现,每个Activity都有一个Window(具体在手机中的完成类是PhoneWindow),Window以下有DecorView,DecorView下面有TitleVie以及ContentView,而ContentView便是咱们在Activity中经过setContentView指定的。
事情传分发机制
ViewGroup有以下三个与事情分发的办法,而View只需dispatchTouchEvent和onTouchEvent。
@Override
publicbooleandispatchTouchEvent(MotionEventev){
returnsuper.dispatchTouchEvent(ev);
}
@Override
publicbooleanonInterceptTouchEvent(MotionEventev){
returnsuper.onInterceptTouchEvent(ev);
}
@Override
publicbooleanonTouchEvent(MotionEventevent){
returnsuper.onTouchEvent(event);
}
事情总是从上往下进行分发,即先到达Activity,再到达ViewGroup,再到达子View,假如没有任何视图消耗事情的话,事情会顺着路径往回传递。其间:
dispatchTouchEvent是事情的分发办法,假如事情能够到达该视图的话,就首要一定会调用,一般咱们不会去修改这个办法。
onInterceptTouchEvent是事情分发的中心办法,表示ViewGroup是否阻拦事情,假如回来true表示阻拦,在这之后ViewGroup的onTouchEvent会被调用,事情就不会往下传递。
onTouchEvent是***级的,在事情分发中***被调用。
子View能够经过requestDisallowInterceptTouchEvent办法去恳求父元素不要阻拦。
留意
事情从Activity.dispatchTouchEvent()开端传递,只需没有被停止或阻拦,从最上层的View(ViewGroup)开端一向往下(子View)传递。子View能够经过onTouchEvent()对事情进行处理。
事情由父View(ViewGroup)传递给子View,ViewGroup能够经过onInterceptTouchEvent()对事情做阻拦,停止其往下传递。
假如事情从上往下传递过程中一向没有被停止,且***层子View没有消费事情,事情会反向往上传递,这时父View(ViewGroup)能够进行消费,假如仍是没有被消费的话,***会到Activity的onTouchEvent()函数。
假如View没有对ACTION_DOWN进行消费,之后的其他事情不会传递过来。
OnTouchListener优先于onTouchEvent()对事情进行消费。
自定义View的分类
对现有的View的子类进行扩展,例如复写onDraw办法、扩展新功能等。
自定义组合控件,把常用一些控件组合起来以方便运用。
直接承继View完成View的完全定制,需求完结View的丈量以及制作。
自定义ViewGroup,需求复写onLayout完结子View方位的确认等作业。
View的丈量-onMeasure
View的丈量最终是在onMeasure办法中经过setMeasuredDimension把代表宽高两个MeasureSpec设置给View,因此需求掌握MeasureSpec。MeasureSpec包含巨细信息以及形式信息。
MeasureSpec的三种形式:
EXACTLY形式:准确形式,对应于用户指定为match_parent或许具体巨细的时分(实际上指定为match_parent实质上是指定巨细为父容器的巨细)
AT_MOST形式:对应于用户指定为wrap_content,此时控件尺度只需不超过父控件允许的***尺度即可。
UNSPECIFIED形式:不指定巨细的丈量形式,这种形式比较少用
下面给出模板代码:
publicclassMeasureUtils{
/**
*用于View的丈量
*
*@parammeasureSpec
*@paramdefaultSize
*@return
*/
publicstaticintmeasureView(intmeasureSpec,intdefaultSize){
intmeasureSize;
//获取用户指定的巨细以及形式
intmode=View.MeasureSpec.getMode(measureSpec);
intsize=View.MeasureSpec.getSize(measureSpec);
//依据形式去回来巨细
if(mode==View.MeasureSpec.EXACTLY){
//准确形式(指定巨细以及match_parent)直接回来指定的巨细
measureSize=size;
}else{
//UNSPECIFIED形式、AT_MOST形式(wrap_content)的话需求提供默许的巨细
measureSize=defaultSize;
if(mode==View.MeasureSpec.AT_MOST){
//AT_MOST(wrap_content)形式下,需求取丈量值与默许值的最小值
measureSize=Math.min(measureSize,defaultSize);
}
}
returnmeasureSize;
}
}
***,复写onMeasure办法,把super办法去掉:
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
setMeasuredDimension(MeasureUtils.measureView(widthMeasureSpec,200),
MeasureUtils.measureView(heightMeasureSpec,200)
);
}
View的制作-onDraw
View制作,需求掌握Android中View的坐标体系:
View的坐标体系是以左上角为坐标原点,向右为X轴正方向,向下为Y轴正方向。
View制作,主要是经过Android的2D绘图机制来完结,时机是onDraw办法中,其间包含画布Canvas,画笔Paint。下面给出示例代码。相关API不是介绍的重点,重点是Canvas的save和restore办法,经过save今后能够对画布进行一些扩大缩小旋转倾斜等操作,这两个办法一般配套运用,其间save的调用次数能够多于restore。
@Override
protectedvoidonDraw(Canvascanvas){
super.onDraw(canvas);
Bitmapbitmap=ImageUtils.drawable2Bitmap(mDrawable);
canvas.drawBitmap(bitmap,getLeft(),getTop(),mPaint);
canvas.save();
//留意,这里的旋转是指画布的旋转
canvas.rotate(90);
mPaint.setColor(Color.parseColor(“#FF4081”));
mPaint.setTextSize(30);
canvas.drawText(“测验”,100,-100,mPaint);
canvas.restore();
}
View的方位-onLayout
与布局方位相关的是onLayout办法的复写,一般咱们自定义View的时分,只需求完结丈量,制作即可。假如是自定义ViewGroup的话,需求做的便是在onLayout中丈量自身以及操控子控件的布局方位,onLayout是自定义ViewGroup必须完成的办法。

未经允许不得转载:IT技术网站 » 事件传递机制以及自定义View相关
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载