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

Android scrollview如何监听滑动状态

程序员文章站 2022-03-31 14:08:02
scrollview 视图的滚动过程,其实是在不断修改原点坐标。当手指触摸后,scrollview会暂时拦截触摸事件,使用一个计时器。假如在计时器到点后没有发生手指移动事件,那么sc...

scrollview

视图的滚动过程,其实是在不断修改原点坐标。当手指触摸后,scrollview会暂时拦截触摸事件,使用一个计时器。假如在计时器到点后没有发生手指移动事件,那么scrollview发送tracking events到被点击的subview;若是在计时器到点后发生了移动事件,那么scrollview取消tracking自己促发滚动。

首先说一下 nestedscrollview 的滑动事件的监听,

如果使用 

nestedscrollview.setonscrollchangelistener(new view.onscrollchangelistener() {
      @override
      public void onscrollchange(view v, int scrollx, int scrolly, int oldscrollx, int oldscrolly) {
 
      }
    });

这个方法在 api >= 23  时才可以使用,怎么解决呢 。我们可以自己定义一个scrollview

public class myscrollview extends nestedscrollview {
   private onscrollchanged monscrollchanged;
  public myscrollview(context context) {
    this(context, null);
  }
  public myscrollview(context context, attributeset attributeset) {
    this(context, attributeset, 0);
  }
  public myscrollview(context context, attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
  }
  @override
  protected void onscrollchanged(int l, int t, int oldl, int oldt) {
    super.onscrollchanged(l, t, oldl, oldt);
    if (monscrollchanged != null) {
      monscrollchanged.onscroll(l, t, oldl, oldt);
    }
  }
  public void setonscrollchanged(onscrollchanged onscrollchanged) {
    this.monscrollchanged = onscrollchanged;
  }
  public interface onscrollchanged {
    void onscroll(int l, int t, int oldl, int oldt);
  }
}

这样我们就可以通过实现 onscrollchanged() 监听滑动事件了 ,其中可以监测到滑动距离,这样就可以做好多事情了;

但是现在有一个需求就是【滑动的时候隐藏 一个靠边的悬浮框,不滑动是悬浮框显示出来】,这样的话就需要监测滑动状态了。scrollview 不像recyclerview一样可以监测滑动状态。

以下是我的一个实现方案,通过countdowntimer 来实现

在刚才的onscrollchanged  接口中增加方法

public interface onscrollchanged {
    void onscroll(int l, int t, int oldl, int oldt);
 
    void ontouch(boolean isdown);
  }

然后重写ontouchevent方法

@override
  public boolean ontouchevent(motionevent ev) {
      switch (ev.getaction()) {
      case motionevent.action_up:
      case motionevent.action_cancel:
        if (monscrollchanged != null) {
          monscrollchanged.ontouch(false);
        }
        break;
      case motionevent.action_down:
      case motionevent.action_move:
        if (monscrollchanged != null) {
          monscrollchanged.ontouch(true);
        }
        break;
    }
    return super.ontouchevent(ev);
  }

这里的isdown=true代表是按下或者滑动的状态,对应action_down和action_move,fale代表action_up和action_cancel

下面使用这个自定义的scrollerview

//静止状态
private final static int scroll_state_idle = 1;
//拖动或者惯性滑动状态
private final static int scroll_state_scroll = 2;
 
//判断是否是拖动状态
boolean isdragstate = false;
 
int currentstate = scroll_state_idle;
 
//这里采用100ms来判断是否已经是静止状态,100ms结束后证明是静止状态
private countdowntimer scrollcounttimer = new countdowntimer(100, 1) {
    @override
    public void ontick(long millisuntilfinished) {
 
    }
 
    @override
    public void onfinish() {
      setscrollstate(scroll_state_idle);
    }
};
 
private void initscrollview() {
    scrollview.setonscrollchanged(new myscrollview.onscrollchanged() {
      @override
      public void onscroll(int l, int t, int oldl, int oldt) {
        if (isdragstate) {//拖动状态单独处理不再进行滚动状态监测
          return;
        }
        //滑动时先取消倒计时,设置滑动状态
        scrollcounttimer.cancel();
        if(currentstate != scroll_state_scroll) {
          setscrollstate(scroll_state_scroll);
        }
        scrollcounttimer.start();
      }
 
      @override
      public void ontouch(boolean isdown) {
        isdragstate = isdown;
        //我这里把按下的状态默认为了滚动的状态,当然你也可以分开定义
        if (isdown) {
          scrollcounttimer.cancel();
          setscrollstate(scroll_state_scroll);
        } else {
          scrollcounttimer.start();
        }
      }
});
//最后记得页面销毁时,cancel掉timer

总结

以上所述是小编给大家介绍的android scrollview如何监听滑动状态,希望对大家有所帮助