Android Scroll实现弹性滑动_列表下拉弹性滑动的示例代码
我这一次讲使用scroll实现弹性滑动,我不会只有一个例子就说完,因为写文章的时候我也在学习,我分几次讲完吧。
首先上一段代码,
privatevoidsmoothScrollByScroller(intdy){
mScroller.startScroll(0,dy,0,dy*-1,1000);
invalidate();
}
@Override
publicvoidcomputeScroll(){
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}
这段代码是实现弹性滑动的核心,第一个函数指的是缓慢滑动的意思,但是却没有这个滑动的实际功能。
startScroll这函数的五个参数指的是起点x坐标,起点y坐标,x位移量,y位移量,这段滑动的时间。这个函数的内部是不断计算在滑动时间里x和y坐标应该是什么值,然后因为invalidate会调用computeScroll,这个computeScrollOffset函数是判断当前滑动是否结束,如果没有结束通过getCurrX和getCurry获得startScroll函数计算的值,在使用scrollTo滑动相应的位置,因为startScroll会运算很多次,也就是将滑动时间分成很多段,相应的坐标也都算出来,跟着给scrollTo去实现滑动。
这很像是ValueAmition,将时间分成很多段,然后计算相应的值,同时分很多次去实现。
我贴一个类似QQ消息列表的常见的弹性滑动,这里下拉是没有刷新的,
publicclassMainActivityextendsAppCompatActivity{
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
publicfinalclassPullViewextendsViewGroup{
privateintmLastY;
privateContextmContext;
privateScrollermScroller;
//子View的个数
privateintmChildCount;
publicPullView(Contextcontext){
this(context,null);
}
publicPullView(Contextcontext,AttributeSetattributeSet){
super(context,attributeSet);
mContext=context;
initView();
}
privatevoidinitView(){
mScroller=newScroller(mContext);
}
@Override
publicbooleanonTouchEvent(MotionEventevent){
inty=(int)event.getY();
switch(event.getAction()){
//手指按下时,初始化按下位置的X,Y位置值
caseMotionEvent.ACTION_DOWN:
mLastY=y;
break;
//计算滑动的偏移量,产生滑动效果
caseMotionEvent.ACTION_MOVE:
//手指向下滑动delayY>0,向上滑动delayY<0
intdelayY=y-mLastY;
delayY=delayY*-1;
scrollBy(0,delayY);
break;
caseMotionEvent.ACTION_UP:
/**
*scrollY是指:View的上边缘和View内容的上边缘(其实就是第一个ChildView的上边缘)的距离
*scrollY=上边缘-View内容上边缘,scrollTo/By方法滑动的知识View的内容
*往下滑动scrollY是负值
*/
intscrollY=getScrollY();
smoothScrollByScroller(scrollY);
break;
}
mLastY=y;
returntrue;
}
/**
*执行滑动效果
*使用scroller实现
*@paramdy
*/
privatevoidsmoothScrollByScroller(intdy){
mScroller.startScroll(0,dy,0,dy*-1,1000);
invalidate();
}
@Override
publicvoidcomputeScroll(){
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}
/**
*重新计算子View的高度和宽度
*@paramwidthMeasureSpec
*@paramheightMeasureSpec
*/
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
intmeasuredWidth;
intmeasureHeight;
mChildCount=getChildCount();
//测量子View
measureChildren(widthMeasureSpec,heightMeasureSpec);
intwidthSpaceSize=MeasureSpec.getSize(widthMeasureSpec);
intwidthSpaceMode=MeasureSpec.getMode(widthMeasureSpec);
intheightSpaceSize=MeasureSpec.getSize(heightMeasureSpec);
intheightSpaceMode=MeasureSpec.getMode(heightMeasureSpec);
//获取横向的padding值
intpaddingLeft=getPaddingLeft();
intpaddingRight=getPaddingRight();
finalViewchildView=getChildAt(0);
/**
*如果子View的数量是0,就读取LayoutParams中数据
*否则就对子View进行测量
*此处主要是针对wrap_content这种模式进行处理,因为默认情况下
*wrap_content等于match_parent
*/
if(mChildCount==0){
ViewGroup.LayoutParamslayoutParams=getLayoutParams();
if(layoutParams!=null){
setMeasuredDimension(layoutParams.width,layoutParams.height);
}else{
setMeasuredDimension(0,0);
}
}elseif(heightSpaceMode==MeasureSpec.AT_MOST&&widthSpaceMode==MeasureSpec.AT_MOST){
measuredWidth=childView.getMeasuredWidth()*mChildCount;
measureHeight=getChildMaxHeight();
//将两侧的padding值加上去
measuredWidth=paddingLeft+measuredWidth+paddingRight;
setMeasuredDimension(measuredWidth,measureHeight);
}elseif(heightSpaceMode==MeasureSpec.AT_MOST){
measureHeight=getChildMaxHeight();
setMeasuredDimension(widthSpaceSize,measureHeight);
}elseif(widthSpaceMode==MeasureSpec.AT_MOST){
measuredWidth=childView.getMeasuredWidth()*mChildCount;
measuredWidth=paddingLeft+measuredWidth+paddingRight;
setMeasuredDimension(measuredWidth,heightSpaceSize);
}
}
/**
*获取子View中最大高度
*@return
*/
privateintgetChildMaxHeight(){
intmaxHeight=0;
for(inti=0;imaxHeight){
maxHeight=height;
}
}
}
returnmaxHeight;
}
/**
*设置子View的布局
*@paramchanged
*@paraml
*@paramt
*@paramr
*@paramb
*/
@Override
protectedvoidonLayout(booleanchanged,intl,intt,intr,intb){
intchildLeft=0;
for(inti=0;i
这里的ViewGroup的绘画和测量我就不多说,我就说一下它获取函数,计算坐标的一些事。
它在手指按下时记录y坐标,在手指移动时,跟着移动子View,在手指抬起时,使用弹性滑动的函数smoothScrollByScroller。
大家会发现为什么一些计算出的坐标要加负号,因为在我们人眼里,我们下拉y坐标的位移量是正的,但是在系统认为这个值是负的,原因我太菜不知道,知道的求大神评论留言告诉。
下一次写一个随手指弹性滑动的例子。
以上这篇AndroidScroll实现弹性滑动_列表下拉弹性滑动的示例代码就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。