欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android界面上拉下拉的回弹效果实例代码

程序员文章站 2023-12-16 14:26:04
废话不多说,具体代码如下所示: public class myscrollview extends scrollview { private view ch...

废话不多说,具体代码如下所示:

public class myscrollview extends scrollview {
  private view childview;
  public myscrollview(context context) {
    super(context);
  }
  public myscrollview(context context, attributeset attrs) {
    super(context, attrs);
  }
  public myscrollview(context context, attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
  }
//  @override
//  protected void onlayout(boolean changed, int l, int t, int r, int b) {
//    super.onlayout(changed, l, t, r, b);
//  }
  //获取子视图
  @override
  protected void onfinishinflate() {
    super.onfinishinflate();
    if (getchildcount() > 0) {
      childview = getchildat(0);
    }
  }
  private int lasty;//上一次y轴方向操作的坐标位置
  private rect normal = new rect();//用于记录临界状态的左、上、右、下
  private boolean isfinishanimation = true;//是否动画结束
  private int lastx, downx, downy;
  //拦截:实现父视图对子视图的拦截
  //是否拦截成功,取决于方法的返回值。返回值true:拦截成功。反之,拦截失败
  @override
  public boolean onintercepttouchevent(motionevent ev) {
    boolean isintercept = false;
    int eventx = (int) ev.getx();
    int eventy = (int) ev.gety();
    switch (ev.getaction()) {
      case motionevent.action_down:
        lastx = downx = eventx;
        lasty = downy = eventy;
        break;
      case motionevent.action_move:
        //获取水平和垂直方向的移动距离
        int absx = math.abs(eventx - downx);
        int absy = math.abs(eventy - downy);
        if(absy > absx && absy >= uiutils.dp2px(10)){
          isintercept = true;//执行拦截
        }
        lastx = eventx;
        lasty = eventy;
        break;
    }
    return isintercept;
  }
  @override
  public boolean ontouchevent(motionevent ev) {
    if (childview == null || !isfinishanimation) {
      return super.ontouchevent(ev);
    }
    int eventy = (int) ev.gety();//获取当前的y轴坐标
    switch (ev.getaction()) {
      case motionevent.action_down:
        lasty = eventy;
        break;
      case motionevent.action_move:
        int dy = eventy - lasty;//微小的移动量
        if (isneedmove()) {
          if (normal.isempty()) {
            //记录了childview的临界状态的左、上、右、下
            normal.set(childview.getleft(), childview.gettop(), childview.getright(), childview.getbottom());
          }
          //重新布局
          childview.layout(childview.getleft(), childview.gettop() + dy / 2, childview.getright(), childview.getbottom() + dy / 2);
        }
        lasty = eventy;//重新赋值
        break;
      case motionevent.action_up:
        if (isneedanimation()) {
          //使用平移动画
          int translatey = childview.getbottom() - normal.bottom;
          translateanimation translateanimation = new translateanimation(0, 0, 0, -translatey);
          translateanimation.setduration(200);
//        translateanimation.setfillafter(true);//停留在最终位置上
          translateanimation.setanimationlistener(new animation.animationlistener() {
            @override
            public void onanimationstart(animation animation) {
              isfinishanimation = false;
            }
            @override
            public void onanimationend(animation animation) {
              isfinishanimation = true;
              childview.clearanimation();//清除动画
              //重新布局
              childview.layout(normal.left, normal.top, normal.right, normal.bottom);
              //清除normal的数据
              normal.setempty();
            }
            @override
            public void onanimationrepeat(animation animation) {
            }
          });
          //启动动画
          childview.startanimation(translateanimation);
        }
        break;
    }
    return super.ontouchevent(ev);
  }
  //判断是否需要执行平移动画
  private boolean isneedanimation() {
    return !normal.isempty();
  }
  private boolean isneedmove() {
    int childmeasuredheight = childview.getmeasuredheight();//获取子视图的高度
    int scrollviewmeasuredheight = this.getmeasuredheight();//获取布局的高度
    log.e("tag", "childmeasuredheight = " + childmeasuredheight);
    log.e("tag", "scrollviewmeasuredheight = " + scrollviewmeasuredheight);
    int dy = childmeasuredheight - scrollviewmeasuredheight;//dy >= 0
    int scrolly = this.getscrolly();//获取用户在y轴方向上的偏移量 (上 + 下 -)
    if (scrolly <= 0 || scrolly >= dy) {
      return true;//按照我们自定义的myscrollview的方式处理
    }
    //其他处在临界范围内的,返回false。即表示,仍按照scrollview的方式处理
    return false;
  }
}

以上所述是小编给大家介绍的android界面上拉下拉的回弹效果实例代码,希望对大家有所帮助

上一篇:

下一篇: