Android自定义View总结(一)基础知识与实例

Android自定义View总结(一)基础知识与实例

2023年7月15日发(作者:)

Android⾃定义View总结(⼀)基础知识与实例⾃定义View是最能体现⼀个Android开发者⽔平的技能之⼀了。接下来的⼀些列博客将总结⼀下Android的⾃定义相关View知识,包括View的结构,事件体系,⼯作原理,⾃定义View的绘制等。参考资料部分来⾃于书上以及各种博客。新建了⼀个qq群 482543750,欢迎⼀起学习的⼩伙伴加⼊。提供各种Android学习资料,⾯试资料,Android简历模板。⼀、概述Android中,View不属于四⼤组件,但它甚⾄⽐Receiver和Provider都要重要。Android提供了许多基础的控件,但远远不能满⾜我们的需要,很多时候我们根据需求进⾏新控件的定义,这就需要我们对View体系有深⼊理解。⼆、基础知识1、View是什么View是Android所有控件的基类,简单到TextView、Button,复杂到RelativeLayout,LinearLayout,其共同基类都是View。所以,View可以理解为控件的抽象,也是⼀个控件。除此之外,还有ViewGroup,字⾯意义上,它表⽰控件组,内部可以包含许多个控件。ViewGroup也继承⾃View,这意味着,⼀个View的可以是单个控件,也可以是多个控件组成的⼀组控件,这就形成了View树。下⾯这个图很好地体现了View的继承关系2、View的相关参数View的位置决定于它的四个顶点,对应View的四个属性:Top:左上⾓纵坐标,通过getTop ()获得Left:左上⾓横坐标,通过getLeft()获得Right: 右下⾓横坐标,通过getRight ()获得Bottom: 右下⾓纵坐标,通过getBottom ()获得这些坐标都是相对于View的⽗容器所说的,是⼀种相对坐标。下⾯这张图表⽰的是View中涉及位置参数的各个⽅法对应的具体含义。最外层是⼿机屏幕,中间是⼀个ViewGroup嵌套⼀个View。涉及到的其他⽅法请继续往下看。 此外,参数x,y表⽰View左上⾓的横纵坐标,translationX和translationY表⽰View的左上⾓相对于⽗容器的偏移量。他们都有相应的Get/Set⽅法这⼏个参数也是相对于⽗容器的坐标可以知道,这⼏个参数换算关系如下x = left + translationXy = top + translationY利⽤这些参数,我们来⾃定义⼀个能随⼿指滑动⽽改变位置的View实现如下效果:初始位置:

⼿指滑动后,⾃定义View⾛到了图⽰位置:代码如下:⾃定义Viewpublic class DragView extends View{ int lastX; int lastY; public DragView(Context context) { super(context); } public DragView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { (canvas); } @Override public boolean onTouchEvent(MotionEvent event) { int x = (int) (); int y = (int) (); Log.e("触发onTouchEvent",x+"::::::"+y); switch (ion()){ case _DOWN:{ lastX = x; lastY = y; } break; case _MOVE:{ int offsetX = x - lastX; int offsetY = y - lastY; Log.e("触发ACTION_MOVE",offsetX+"::::::"+offsetY); layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY); Log.d("DragView",getLeft()+"______"+getTop()+"-------"+getBottom()+"-------"+getRight()); } break; } return true; }}布局: MainActivity直接显⽰布局即可很好地实现了如上效果3、MotionEvent和TouchSlop(1)MotionEvent我们在⾃定义View的时候,常常需要在onTouchEvent()中定义触摸⾏为典型的触摸事件类型包括:ACTION_DOWN:⼿指刚刚接触屏幕ACTION_MOVE:⼿指在屏幕上移动ACTION_UP:⼿指从屏幕离开通过MotionEvent对象,我们可以得到点击事件的⼀系列位置参数getX(),getY():触摸事件发⽣的位置相对于View的坐标getRawX(),getRawY()返回返回相对于屏幕左上⾓的x 和 y 坐标(2)TouchSlop表⽰系统能辨识出的认为是滑动的最⼩距离。若两次滑动⼩于此常量,判定为不属于滑动操作这个常量的⼤⼩和⼿机有关。通过如下⽅式获得:(getContext()).getScaledTouchSlop();我们处理滑动事件时,可以⽤这个参数进⾏过滤。4、VelocityTracker、GestureDetector、Scroller(1)VelocityTracker⽤于追踪滑动过程中的速度,包括⽔平和竖直⽅向的速度。使⽤⽅法:在View的onTouchEvent()中将Event托管给VelocityTracker,采⽤相应API获取参数//获取对象VelocityTracker velocityTracker = ();//托管ement(event);//设置时间间隔,结果会表⽰为每1000毫秒经过多少像素,若设置为100,结果表⽰为没100毫秒经过多少像素eCurrentVelocity(1000);//获取X和Y⽅向上的速度int xVelicity = (int) locity();int yVelicity = (int) locity();⽐如1秒内X⽅向滑动了100像素,那么参数设置为1000时,结果就为100,表⽰1000毫秒划过100像素参数设置为100时,结果就为10(表⽰每100毫秒划过10像素)不需要使⽤时,对其进⾏回收();e();(2)GestureDetectorGestureDetector中将封装了⼀系列触摸⾏为,包括单击、滑动、长按,双击等。使⽤:在⾃定义View中实现onGestureDetector接⼝,在其中重写onSingleTapTop()-单击事件、onFiling()-快速滑动、omLongPress()-长按、onDoubleTap()-双击等⽅法,定义⾃⼰的事件处理逻辑还有,在onTouchEvent()中://获取对象GestureDetector gestureDetector = new GestureDetector(this);//解决长按屏幕后⽆法拖动的问题ongpressEnabled(false);//托管eventboolean consume = hEvent(event);return consume;(3)Scroller⽤于实现View的弹性滑动。为了让View实现滑动,我们常常使⽤scrollTo和ScrollBy,但其过程是瞬间完成的,没有过度效果,⽤户体验并不好。使⽤Scroller和View的computeScroll配合,可以实现有过渡效果的滑动三、View的滑动滑动是⾃定义View使⽤最多的效果之⼀,有三种实现⽅式:a、View的scrollTo/ScrollBy⽅法b、使⽤动画为View施加平移效果c、改变View的LayoutParams是的View重新布局实现滑动1、使⽤scrollTo/ScrollBy源码:/** * Set the scrolled position of your view. This will cause a call to * {@link #onScrollChanged(int, int, int, int)} and the view will be * invalidated. * @param x the x position to scroll to * @param y the y position to scroll to */public void scrollTo(int x, int y) { if (mScrollX != x || mScrollY != y) { int oldX = mScrollX; int oldY = mScrollY; mScrollX = x; mScrollY = y; invalidateParentCaches(); onScrollChanged(mScrollX, mScrollY, oldX, oldY); if (!awakenScrollBars()) { postInvalidateOnAnimation(); } }}/** * Move the scrolled position of your view. This will cause a call to * {@link #onScrollChanged(int, int, int, int)} and the view will be * invalidated. * @param x the amount of pixels to scroll by horizontally * @param y the amount of pixels to scroll by vertically */public void scrollBy(int x, int y) { scrollTo(mScrollX + x, mScrollY + y);}scrollBy实际上也调⽤scrollTo⽅法,实现基于当前位置的滑动,scrollTo实现基于所传递参数的绝对滑动mScrollX和mScrollY可以动过get⽅法得到。mScrollX的值总是等于View的左边缘到View的内容左边缘⽔平⽅向的距离,mScrollY的值总是等于View的上边缘和View的内容上边缘竖直⽅向的距离。需要注意的是,scrollBy和scrollTo 只能改变View的内容的位置⽽不能改变View在布局中的位置在View的内容位置改变是,mScrollX和mScrollY值可正可负2、使⽤动画通过动画可以让⼀个View进⾏平移,主要是操作View的translationX和translationY属性,可以⽤View动画,也可以⽤属性动画。以属性动画为例,我们在上⾯例⼦的基础上添加⼀个按钮

点击按钮,View在1秒钟的时间内向右平移200像素通过如下代码:Button button = (Button) findViewById();lickListener(new kListener() { @Override public void onClick(View v) { e().translationX(200).setDuration(1000).start(); }});3.改变布局参数即改变LayoutParams,⽐如我们让以上⾃定义View向右平移100像素只要将此View的marginLeft参数值增加100px同样以上为例,将⾃定义View的宽度增加100px,向右平移lickListener(new kListener() { @Override public void onClick(View v) { Params layoutParams = (Params) outParams(); +=100; rgin+=100; tLayout(); //或者outParams(layoutParams); }});点击按钮发现View向右滑动⽽且变胖了,但是瞬间滑动过去的,没有动画效果

发布者:admin,转转请注明出处:http://www.yc00.com/web/1689430720a247057.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信