作者分享了自己对View相关知识的理解,有兴趣的可以学习一下。有不同意见欢迎留言~另外,作者没有提供案例。如果有兴趣,可以针对问题,考虑实际使用场景,提供一个实际案例,那就更好了。一、View坐标(一)View的主要坐标参数有哪些?有哪些注意事项?主要的坐标参数有:1)Left,Right,top,Bottom;它们不代表距离屏幕左上角的绝对距离值,而是代表view与其父控件的相对坐标值,代表View的初始坐标,绘制完成后不会改变。2)X和Y表示View的左上角相对于父控件的坐标值,即实时相对坐标。3)TranslationX和TranslationY这两个值默认都是0,表示相对于父控件左上角的偏移量。它们之间的转换关系是:x=left+translationX;y=top+translationY;width=right-left;height=bottom-top;left=getLeft();(2)View中几个重要的方法?1)onMeasure(widthMeasureSpec,heightMeasureSpec)onMeasure过程决定了View的宽高。Measure完成后,可以通过getMeasureWidth和getMeasureHeight方法获取View的测量宽高。几乎在所有情况下,它都会等于最终视图的宽高onMeasure()方法接收两个参数,widthMeasureSpec和heightMeasureSpec,这两个值用来确定宽高的规格和大小分别查看。2)onLayout(booleanchanged,intleft,inttop,intright,intbottom)布局过程决定了View的四个顶点的坐标和View的实际宽高。完成后可以使用getTop、getBottom、getLeft、getRight获取View的四个顶点位置,通过getWidth和getHeight获取View最终的宽高3)onDraw(Canvas画布)绘制过程决定显示的视图。绘制完成后会在屏幕上显示视图绘制背景(background.draw(Canvas))绘制自己保护voidonDraw(Canvascanvas)onDraw绘制自己,新建一个paint在画布上绘制自己的图形drawchildren(dispatchDraw)dispatchDraw会遍历并调用所有子元素的draw方法drawdecoration(onDrawScrollBars)4)isEnabled()当前视图是否可用。您可以调用setEnable()方法来更改视图的可用状态。传true表示可用,传false表示不可用。它们最大的区别是不可用视图不能响应onTouch事件。5)isFocused()当前视图是否有焦点一般情况下,有两种方法可以使视图获得焦点,即通过键盘上下左右键切换视图,调用requestFocus()方法。而且现在安卓手机几乎没有键盘,所以基本上只能通过requestFocus()来获取视图的焦点。requestFocus()方法不能保证view能获得焦点,它会有一个boolean返回值,如果返回true,表示获得焦点成功,如果返回false,表示聚焦失败.一般view只有在touch模式下既是focusable又是focusable的时候才能成功获得焦点,比如EditText。6)offsetTopAndBottom(intoffset)和offsetLeftAndRight(intoffset)offsetTopAndBottom直接改变top和bottom,相当于在parent中上下平移View的位置;offsetLeftAndRight直接改变左右,相当于左右平移View在parent的位置;直接改变了View的边界,因为View和它的子View的相对位置没有改变,所以它的子View的边界也改变了。(3)获取到的View宽高为0怎么办?如果我们要获取一个视图的位置坐标,可以在findviewbyid之后直接获取,或者在视图的点击事件中获取,或者在其他地方获取。如果我们在finedviewbyid之后直接获取,有时会获取失败,获取到的值为0;分析可能有以下三种原因:1)view本身的宽高为0;2)View的visibility属性没有了;3)视图还没有绘制。当然,画的不完整还表现在不同的方面。比如activity代表的界面还没有显示出来,没有添加到WindowPhone的DecorView中;获取的视图还没有添加到DecorView中。我们主要想谈的是第三种情况,如何解决呢?1)在View的事件回调中获取;此时view已经显示并添加到DecorView中,如click事件,touch事件,focus事件等。2)在activity显示时,添加到DecorView中获取宽高,如作为onWindowFocusChanged()回调方法3)在onResume方法中通过post(Runnable)4)在onCreate()或onResume()方法中需要获取宽高时使用getViewTreeObserver().addOnGlobalLayoutListener()添加回调到视图。在回调中获取宽度或高度,让视图删除回调5)view.measure(intwidthMeasureSpec,intheightMeasureSpec)手动测量视图,获取视图的宽度High(这个方法比较特殊,需要考虑传入spec)2.Viewsliding1.viewslide有几种方法。你应该注意什么?它们适用于那些场景吗?1)通过视图自身提供的scrollTo和scrollToscrollBy进行滑动;但是你只能滑动视图的内容,不能滑动视图本身。比如textview调用这两个方法时,滑动的就是显示的word内容。详见http://www.jianshu.com/p/2b48551d531922)使用补间动画平移视图。平移视图的补间动画是对视图图像的操作,并不能真正改变视图的位置参数。3)使用属性动画平移viewObjectAnimator.ofFloat(view,"translationX",0,500).setDuration(2000).start();ObjectAnimator.ofFloat(view,"translationY",0,500).setDuration(2000).start();属性动画panview需要兼容3.0以下版本4)通过改变view的LayoutParams,重新布局view实现滑动ViewGroup.MarginLayoutParamsparams=view.getLayoutParams();params.leftMargin+=500;(2)scrollTo和scrollBy三种滑动方法比较scrollBy方法使用简单,操作方便,但是只能滑动view的内容,不能直接滑动view本身来补间动画滑动。它是对视图图像的操作。它也不能真正改变视图的位置参数属性。动画滑动可以改变view的position参数,但是需要兼容3.0以下的LayoutParams版本。使用起来有点麻烦。在交互式视图中使用动画(非属性动画)来实现视图的滑动会有什么后果(三)?Answer:Actual上层view动画是view的surfaceui的运动,也就是呈现给用户的视觉效果。动画本身不能移动视图的真实位置,属性动画除外。动画播放完毕后,视图最终会回到原来的位置。当然,你可以设置FillAfter属性,让view外观在动画结束后停留在变化的位置。所以这会产生非常严重的后果。例如,如果您的按钮位于屏幕的左侧,您现在可以使用动画并设置fillafter属性使其移至右侧。你会发现点击右边的按钮不会触发点击事件,但是点击左边的按钮可以触发。原因是右边的按钮只是view的表象,左边真正的按钮还没有动。如果一定要这样做,可以在右边按钮移动过的位置预先放置一个新的按钮,当动画结束后,让右边的可见,左边的消失。(4)view的滑动渐变效果有哪些方法?一共有三种,第一种是Scroller,也是用的最多的。第二种是动画。动画我就不说了,不属于本文讨论范围。第三种也是我们经常使用的是使用处理程序每??隔一个时间间隔更新视图的状态。(5)onTouchEvent和GestureDetector什么时候用比较好?当只有滑动需求时使用前者,当有双击等行为时使用后者。
