Android View的滑动
来源:互联网 发布:如何查看数据库主键 编辑:程序博客网 时间:2024/05/29 09:37
view的位置参数
view的位置中,经常会碰到几个获取位置参数方法,如getX()
,getScrollX
,getLeft()
等,在View绘制过程中,其位置是由四个顶点来决定,其分别是top
,left
,right
,bottom
,但需的注意的一点是:其位置是相对于父容器,而不是相对于屏幕的,就如下图:
在获取view的宽和高,通常会调用getWidth()
和getHeight()
两个方法,从源码来看便知道有如下关系: width=right-left
height=bottom-top
在android3.0以后,android就增加了属性动画,其属性动画会影响view的本身位置等属性,但view动画是不会影响view的本身位置属性,它仅会影响到其的内容的位置变化。在Vie中,有几个重要的位置记录参数,x
,y
,translationX
,translationY
,其中x
和y
是view左上角的坐标(其坐标也是相对于父容器),而translationX
和translationY
是View左上角相对于父容器的偏移量,但其两个默认都是零。
那么getX()
和getY()
跟上面几个参数有如何关系,看如下android源码:
/** * A Property wrapper around the <code>x</code> functionality handled by the * {@link View#setX(float)} and {@link View#getX()} methods. */public static final Property<View, Float> X = new FloatProperty<View>("x") { @Override public void setValue(View object, float value) { object.setX(value); } @Override public Float get(View object) { return object.getX(); }};/** * Sets the visual x position of this view, in pixels. This is equivalent to setting the * {@link #setTranslationX(float) translationX} property to be the difference between * the x value passed in and the current {@link #getLeft() left} property. * * @param x The visual x position of this view, in pixels. */public void setX(float x) { setTranslationX(x - mLeft);}/** * The visual x position of this view, in pixels. This is equivalent to the * {@link #setTranslationX(float) translationX} property plus the current * {@link #getLeft() left} property. * * @return The visual x position of this view, in pixels. */@ViewDebug.ExportedProperty(category = "drawing")public float getX() { return mLeft + getTranslationX();}
因此便知其换算关系:getX()=x=left+translationX
,getY()=y=top+translationY
,因此在view动画的平移过程中,并不会影响top
,left
,right
,bottom
的值,而是改变translationX
,translatinY
的值。
我们知道我们最常用的一种滑动实现是使用Scroller
,scrollTo
,scrollBy
等组合,在这些实现当中,有两个重要位置信息参数就是mScrollX
和mScrollY
,其默认都是零.其mScrollX
代表View左边缘和View内容左边缘在水平方向的距离,而mScrollY
代表View上边缘和View内容上边缘在竖直方向的距离,其关系如图:
其换算关系:mScrollX=View左边缘-View内容左边缘
,mScrollY=View上边缘-View内容上边缘
,因此要让View组件相对于View内容从左到右滑动,那么设置mScrollX为负数,即可调用scrollTo(负数,0)
或scrollBy(负数,0)
,同理,要让View组件相对于View内容从下到上滑动,那么设置mScrollY为负数,即可调用scrollTo(0,负数)
或scrollBy(0,负数)
.
MotionEvent的位置参数
在android点击触发事件中,我们经常会碰到四个方法,getX()
,getY()
,getRawX()
,getRawY()
,那么getX()
和getRawX()
有什么区别呢?
其中getX()
是相对于View本身位置而言,而getRawX()
是相对于屏幕而言,同理getY()
和getRawY()
也一样,具体区别如图:
实践demo:
我就实现一个listView
的侧滑删除功能来作为这次学习成果,以下是核心代码:
//slide logicpublic boolean onSlide(MotionEvent event){ switch (event.getAction()){ case MotionEvent.ACTION_DOWN: stopScroll(); mDownX=(int)event.getX(); break; case MotionEvent.ACTION_MOVE: int dis=(int)(mDownX-event.getX()); //when mBackGroundView has been opened and user slide this item again. if(state== STATE_OPEN){ dis+=mBackGroundView.getWidth()*mSwipeDirection; } swipe(dis); break; case MotionEvent.ACTION_UP: int halfWith=0; //whether distance of item's slide is beyond its half. if(mSwipeDirection==DIRECTION_LEFT){ halfWith=mContentView.getWidth()-mBackGroundView.getLeft(); }else if(mSwipeDirection==DIRECTION_RIGHT){ halfWith=mBackGroundView.getWidth()+mBackGroundView.getLeft(); } if(Math.abs(halfWith)>(mBackGroundView.getWidth()>>1)&&!isAutoSpringBack){ smoothOpenItem(); }else{ smoothCloseItem(); return false; } break; } return true; } //using layout() method to implement slide private void swipe(int dis){ if(!mSwipEnable){ return; } //whether user is silding the item. if(Math.signum(dis)!=mSwipeDirection){ dis=0; }else if(Math.abs(dis)> mBackGroundView.getWidth()){ dis=mBackGroundView.getWidth()*mSwipeDirection; } mContentView.layout(-dis, mContentView.getTop(), mContentView.getWidth() -dis, getMeasuredHeight()); if (mSwipeDirection == DIRECTION_LEFT) { mBackGroundView.layout(mContentView.getWidth() - dis, mBackGroundView.getTop(), mContentView.getWidth() + mBackGroundView.getWidth() - dis, mBackGroundView.getBottom()); } else { mBackGroundView.layout(-mBackGroundView.getWidth() - dis, mBackGroundView.getTop(), - dis, mBackGroundView.getBottom()); } } /** * when {@link #smoothCloseItem()} or {@link #smoothOpenItem()} is called,it will be invoked. * * @see #smoothCloseItem() * @see #smoothOpenItem() */ @Override public void computeScroll() { if (state == STATE_OPEN) { if (mOpenScroller.computeScrollOffset()) { swipe(mOpenScroller.getCurrX()*mSwipeDirection); postInvalidate(); }else{ if(mOnSlideStopCallBack !=null&&isCallStopCallBack){ isCallStopCallBack=false; mOnSlideStopCallBack.openStop(this,position); } } } else { if (mCloseScroller.computeScrollOffset()) { swipe((mBaseX - mCloseScroller.getCurrX())*mSwipeDirection); postInvalidate(); }else { if(mOnSlideStopCallBack !=null&&isCallStopCallBack){ isCallStopCallBack=false; mOnSlideStopCallBack.closeStop(this,position); } } } }
效果:
Demo地址:https://github.com/scau-beyondboy/SlideItemToDelete
- Android View的滑动
- Android View的滑动
- Android中View的滑动
- Android 中 View 的滑动
- 【Android】Android View的滑动实现
- android横向滑动选择的view
- Android View 的弹性滑动: Scroller使用说明
- Android学习笔记 3.2View的滑动
- Android中View的滑动冲突
- [Android] 滑动 View 的原理及处理
- Android中View的滑动方式
- android view滑动的三种方式
- android view滑动的几种方法
- android View滑动冲突的解决方式
- Android开发进阶—View的滑动
- Android开发——View的滑动
- Android中View的滑动机制分析
- Android View滑动相关的基础知识点
- HDU1271-Arbitrage
- 真的好苦涩
- Map<String,String> rm=new HashMap<String,String>(2)这个2是什么意思?
- 关于AIDL的跨进程通信
- Git 避免重复输入用户名和密码方法
- Android View的滑动
- 【算法学习】将MSRCR中的模糊处理由FFT修改为时域纯高斯模糊
- 动态规划思想分析——经典题目
- linux rysnc命令详解
- 五大主流数据库模型
- refreshed 问题
- 一个帖子学会Android开发四大组件
- java Thread join方法
- 我对MVVM的理解