三种布局实现上下回弹效果(普通布局,ListView,ScrollView)

 

本文主要介绍不超出屏幕边界的普通布局,ListView,ScrollView三种布局上下回弹效果的实现。

实现流程:

            1.新建一个类继承LinearLayout

            2.覆写方法三个方法onLayout(boolean changed, int l, int t, int r, int b),computeScroll(),onTouchEvent(MotionEvent event)

             3.在构造方法中实例化Scroller;
             4.在OnLayout里面实例化子布局
             5.在OnonTouchEvent里面进行手势判断,
             6.在computeScroll()里面完成实际的滚动 

由于本人深恶痛绝下载源码需要财富的现象,现把源码放在这里http://yunpan.cn/QIbyJehZjthDq与大家分享,代码稍微改一下就可以实现一切布局的回弹效果

这里只实现ScrollView回弹效果,其他一切布局的回弹效果的实现均雷同于此

代码如下:
package com.example.scrollview.springback;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Scroller;

public class ScrollViewLinearLayout extends LinearLayout implements OnTouchListener{
 
 private LinearLayout top;
// private LinearLayout.LayoutParams top_lp ;
 private ScrollView sv;
 private boolean isfrist =true;
 private float y1,y2;
 private int hight=60;
 private Scroller mScroller;

 public ScrollViewLinearLayout(Context context, AttributeSet attrs) {
  super(context, attrs);
  
  setClickable(true); 
        setLongClickable(true);
  mScroller = new Scroller(context);
  
 }

    protected void smoothScrollBy(int dx, int dy) { 
        //设置mScroller的滚动偏移量 
        mScroller.startScroll(0, mScroller.getFinalY(), 0, dy); 
        invalidate();//这里必须调用invalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果 
    } 
   
   protected void smoothScrollTo(int fx, int fy) { 
        int dx = fx - mScroller.getFinalX(); 
        int dy = fy - mScroller.getFinalY(); 
         smoothScrollBy(0, dy); 
     } 
 
 
 
 @SuppressLint("NewApi")
 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
  super.onLayout(changed, l, t, r, b);
  if(changed&&isfrist){//只需实例化一次
   sv= (ScrollView) getChildAt(0);//该自定义布局写入xml文件时,其子布局的第一个必须是ScrollView时,这里才能getChildAt(0),实例化ScrollView
   sv.setOverScrollMode(View.OVER_SCROLL_NEVER);//去掉ScrollView 滑动到底部或顶部 继续滑动时会出现渐变的蓝色颜色快

   sv.setOnTouchListener(this);
   isfrist=false;
   
  }
  
 }


  @Override 
     public void computeScroll() { 
         if (mScroller.computeScrollOffset()) {  //判断mScroller滚动是否完成 
             scrollTo(mScroller.getCurrX(), mScroller.getCurrY());  //这里调用View的scrollTo()完成实际的滚动 
             postInvalidate(); 
         } 
         super.computeScroll(); 
     } 

 

 @Override
 public boolean onTouch(View v, MotionEvent event) {
  switch (event.getAction()) {
 case MotionEvent.ACTION_DOWN:    
  y1= event.getY();
  break;          
  case MotionEvent.ACTION_MOVE:
   y2= event.getY();
   int scrollY=v.getScrollY();              
   int height=v.getHeight();                
   int scrollViewMeasuredHeight=sv.getChildAt(0).getMeasuredHeight();
   if(y2-y1>0&&v.getScrollY()<=0){//头部回弹效果
    smoothScrollTo(0,-(int) ((y2-y1)/2));
    System.out.println("topMargin="+((int) ((y2-y1)/2)));
    return false;
   }
   
   if(y2-y1<0&&(scrollY+height)==scrollViewMeasuredHeight){//底部回弹效果
    smoothScrollTo(0,-(int) ((y2-y1)/2));
    return false;
   }
   
  break;
  case MotionEvent.ACTION_UP:
    smoothScrollTo(0, 0); //松开手指,自动回滚
    break;
  default:               
   break;
 }
  return false;
 }

}

 需要注意的有以下几点:

      1.mScroller.startScroll(0, mScroller.getFinalY(), 0, dy); 后必须invalidate();才能调用computeScroll()看到滚动效果

      2.Scroller 的滚动坐标是屏幕左上角为坐标原点,往右是+x,往下是-y.(这一点在计算坐标时一定要明白,否则很难理解坐标的计算)

      3.该自定义布局写入xml文件时,其子布局的第一个必须是ScrollView时,在OnLayout()方法才能getChildAt(0)实例化ScrollView

      4.上下回弹效果的关键方法是判断ScrollView何时到头部和底部,这样才能触发拉伸,回弹效果

 

           

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值