当前位置: 移动技术网 > 移动技术>移动开发>Android > android开发通过Scroller实现过渡滑动效果操作示例

android开发通过Scroller实现过渡滑动效果操作示例

2020年03月09日  | 移动技术网移动技术  | 我要评论

本文实例讲述了android开发通过scroller实现过渡滑动效果。分享给大家供大家参考,具体如下:

主要介绍一下scroller这个类,它可以实现过渡滑动的效果,使滑动看起来不是那么生硬,当然它用大量的重绘来实现,invalidate();通过源码看:

看构造方法

 /**
   * create a scroller with the default duration and interpolator.
   */
  public scroller(context context) {
    this(context, null);
  }
  /**
   * create a scroller with the specified interpolator. if the interpolator is
   * null, the default (viscous) interpolator will be used. "flywheel" behavior will
   * be in effect for apps targeting honeycomb or newer.
   */
  public scroller(context context, interpolator interpolator) {
    this(context, interpolator,
        context.getapplicationinfo().targetsdkversion >= build.version_codes.honeycomb);
  }
  /**
   * create a scroller with the specified interpolator. if the interpolator is
   * null, the default (viscous) interpolator will be used. specify whether or
   * not to support progressive "flywheel" behavior in flinging.
   */
  public scroller(context context, interpolator interpolator, boolean flywheel) {
    mfinished = true;
    if (interpolator == null) {
      minterpolator = new viscousfluidinterpolator();
    } else {
      minterpolator = interpolator;
    }
    mppi = context.getresources().getdisplaymetrics().density * 160.0f;
    mdeceleration = computedeceleration(viewconfiguration.getscrollfriction());
    mflywheel = flywheel;
    mphysicalcoeff = computedeceleration(0.84f); // look and feel tuning
  }

我们用默认的就行,传个context就行了,其他的什么差值器,先不管了

然后调用startscroll,传递我们歧视滑动位置和滑动的偏移量,还有可选的默认持续时间,默认为250毫秒
这个方法是用来赋值的,接下来会调用invalidate()进行重新绘制,然后就会ondraw(),这时候会调用
computescroll()这个方法,我们重写这个方法,computescrolloffset()是判断动画有没有结束的一个方法,没结束的时候,我们根据滑动的偏移位置进行移动也就是scrollto到scroller的当前位置,再次调用invalidate(),由此无数的重回进行拼接形成了平滑的滑动

/**
   * call this when you want to know the new location. if it returns true,
   * the animation is not yet finished.
   */
  public boolean computescrolloffset() {
    if (mfinished) {
      return false;
    }
    int timepassed = (int)(animationutils.currentanimationtimemillis() - mstarttime);
    if (timepassed < mduration) {
      switch (mmode) {
      case scroll_mode:
        final float x = minterpolator.getinterpolation(timepassed * mdurationreciprocal);
        mcurrx = mstartx + math.round(x * mdeltax);
        mcurry = mstarty + math.round(x * mdeltay);
        break;
      case fling_mode:
        final float t = (float) timepassed / mduration;
        final int index = (int) (nb_samples * t);
        float distancecoef = 1.f;
        float velocitycoef = 0.f;
        if (index < nb_samples) {
          final float t_inf = (float) index / nb_samples;
          final float t_sup = (float) (index + 1) / nb_samples;
          final float d_inf = spline_position[index];
          final float d_sup = spline_position[index + 1];
          velocitycoef = (d_sup - d_inf) / (t_sup - t_inf);
          distancecoef = d_inf + (t - t_inf) * velocitycoef;
        }
        mcurrvelocity = velocitycoef * mdistance / mduration * 1000.0f;
        mcurrx = mstartx + math.round(distancecoef * (mfinalx - mstartx));
        // pin to mminx <= mcurrx <= mmaxx
        mcurrx = math.min(mcurrx, mmaxx);
        mcurrx = math.max(mcurrx, mminx);
        mcurry = mstarty + math.round(distancecoef * (mfinaly - mstarty));
        // pin to mminy <= mcurry <= mmaxy
        mcurry = math.min(mcurry, mmaxy);
        mcurry = math.max(mcurry, mminy);
        if (mcurrx == mfinalx && mcurry == mfinaly) {
          mfinished = true;
        }
        break;
      }
    }
    else {
      mcurrx = mfinalx;
      mcurry = mfinaly;
      mfinished = true;
    }
    return true;
  }

 public void startscroll(int startx, int starty, int dx, int dy) {
    startscroll(startx, starty, dx, dy, default_duration);
  }
 public void startscroll(int startx, int starty, int dx, int dy, int duration) {
    mmode = scroll_mode;
    mfinished = false;
    mduration = duration;
    mstarttime = animationutils.currentanimationtimemillis();
    mstartx = startx;
    mstarty = starty;
    mfinalx = startx + dx;
    mfinaly = starty + dy;
    mdeltax = dx;
    mdeltay = dy;
    mdurationreciprocal = 1.0f / (float) mduration;
  }

public class movefreeview extends view{
  private int movedx;
  private int movedy;
  private scroller mscroller;
  public movefreeview(context context) {
    super(context);
  }
  public movefreeview(context context, @nullable attributeset attrs) {
    super(context, attrs);
    mscroller = new scroller(context);
  }
  public movefreeview(context context, @nullable attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
  }
  @override
  public boolean ontouchevent(motionevent event) {
    //获取触摸点到边界坐标
    int x = (int) event.getx();
    int y = (int) event.gety();
    switch (event.getaction()){
      case motionevent.action_down:
        movedx = x;
        movedy = y;
        break;
      case motionevent.action_move:
        int offsetx = x-movedx;
        int offsety = y-movedy;
        layout(getleft()+offsetx,gettop()+offsety,getright()+offsetx,getbottom()+offsety);
        break;
    }
    return super.ontouchevent(event);
  }
  //供外界调用通过传递x,y的的滑动距离
  public void smoothscrollto(int destinyx,int destinyy){
    //向右侧,下方滑动,请传递负值
    int scrollx = getscrollx();
    int scrolly = getscrolly();
    int delta = destinyx - scrollx;
    int deltay = destinyy - scrolly;
    mscroller.startscroll(scrollx,scrolly,delta,deltay,5000);
    invalidate();
  }
  @override
  public void computescroll() {
    super.computescroll();
    //true则表示滑动未结束
    if (mscroller.computescrolloffset()){
      ((view) getparent()).scrollto(mscroller.getcurrx(),mscroller.getcurry());
      invalidate();
    }
  }
}

private movefreeview button;
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
    button = (movefreeview) findviewbyid(r.id.custon);
    button.smoothscrollto(-400,-300);
    //    button.startanimation(animationutils.loadanimation(this,r.anim.translate));
//    objectanimator animtor1 = objectanimator.offloat(button, "translationx", 0, 300);
//    objectanimator animtor2 = objectanimator.offloat(button, "translationy", 0, 300);
//    objectanimator animator3 = objectanimator.offloat(button,"rotationx",0.0f,360f);
//    objectanimator animator4 = objectanimator.offloat(button,"scalex",1.5f,0.5f);
//    animatorset set= new animatorset();
//    set.setduration(5000);
//    set.playtogether(animtor1,animtor2,animator3,animator4);
//    set.addlistener(new animator.animatorlistener() {
//      @override
//      public void onanimationstart(animator animator) {
//
//      }
//
//      @override
//      public void onanimationend(animator animator) {
//        //动画结束时做一些事情
//      }
//
//      @override
//      public void onanimationcancel(animator animator) {
//
//      }
//
//      @override
//      public void onanimationrepeat(animator animator) {
//
//      }
//    });
//    set.start();
  }
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网