精华内容
下载资源
问答
  • scrollview监听滑动位置

    2016-02-21 09:11:41
    Android监听ScrollView滑动到顶端和底部     package cn.testscrollview; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view....
    Android监听ScrollView滑动到顶端和底部
     
     
    package cn.testscrollview;
    import android.os.Bundle;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.widget.ScrollView;
    import android.app.Activity;
    /**
      * Demo描述:
      * 监听ScrollView滑动到顶端和底部
      *
      * 注意事项:
      * 1 mScrollView.getChildAt(0).getMeasuredHeight()表示:
      *   ScrollView所占的高度.即ScrollView内容的高度.常常有一
      *   部分内容要滑动后才可见,这部分的高度也包含在了
      *   mScrollView.getChildAt(0).getMeasuredHeight()中
      *  
      * 2 view.getScrollY表示:
      *   ScrollView顶端已经滑出去的高度
      *  
      * 3 view.getHeight()表示:
      *   ScrollView的可见高度
      *  
      */
    public class MainActivity extends Activity {
         private ScrollView mScrollView;
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super .onCreate(savedInstanceState);
             setContentView(R.layout.main);
             init();
         }
         private void init(){
             mScrollView=(ScrollView) findViewById(R.id.scrollView);
             mScrollView.setOnTouchListener( new TouchListenerImpl());
         }
         private class TouchListenerImpl implements OnTouchListener{
             @Override
             public boolean onTouch(View view, MotionEvent motionEvent) {
                 switch (motionEvent.getAction()) {
                 case MotionEvent.ACTION_DOWN:
     
                     break ;
                 case MotionEvent.ACTION_MOVE:
                      int scrollY=view.getScrollY();
                      int height=view.getHeight();
                      int scrollViewMeasuredHeight=mScrollView.getChildAt( 0 ).getMeasuredHeight();
                      if (scrollY== 0 ){
                             System.out.println( "滑动到了顶端 view.getScrollY()=" +scrollY);
                         }
                      if ((scrollY+height)==scrollViewMeasuredHeight){
                             System.out.println( "滑动到了底部 scrollY=" +scrollY);
                             System.out.println( "滑动到了底部 height=" +height);
                             System.out.println( "滑动到了底部 scrollViewMeasuredHeight=" +scrollViewMeasuredHeight);
                         }
                     break ;
     
                 default :
                     break ;
                 }
                 return false ;
             }
             
         };
    }
    展开全文
  • Android scrollview监听滑动状态

    千次阅读 2019-12-25 22:28:43
    首先说一下NestedScrollView 的滑动事件的监听, 如果使用 nestedScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() { @Override public void onScrollChange(View v, int scroll...

    首先说一下 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没有像ListView那样,使用setOnScrollListener监听滑动事件,通过自定义的View可以实现,源码如下: package com.ql.view; import android.content.Context; import android.os.Handler; ...

    Android的ScrollView没有像ListView那样,使用setOnScrollListener监听滑动事件,通过自定义的View可以实现,源码如下:

    package com.ql.view;  
      
    import android.content.Context;  
    import android.os.Handler;  
    import android.os.Message;  
    import android.util.AttributeSet;  
    import android.view.MotionEvent;  
    import android.view.View;  
    import android.widget.ScrollView;  
       
    public class LazyScrollView extends ScrollView{  
        private static final String tag="LazyScrollView";  
        private Handler handler;  
        private View view;  
        public LazyScrollView(Context context) {  
            super(context);  
            // TODO Auto-generated constructor stub  
        }  
        public LazyScrollView(Context context, AttributeSet attrs) {  
            super(context, attrs);  
            // TODO Auto-generated constructor stub  
        }  
        public LazyScrollView(Context context, AttributeSet attrs, int defStyle) {  
            super(context, attrs, defStyle);  
            // TODO Auto-generated constructor stub  
        }  
        //这个获得总的高度  
        public int computeVerticalScrollRange(){  
            return super.computeHorizontalScrollRange();  
        }  
        public int computeVerticalScrollOffset(){  
            return super.computeVerticalScrollOffset();  
        }  
        private void init(){  
              
            this.setOnTouchListener(onTouchListener);  
            handler=new Handler(){  
                @Override  
                public void handleMessage(Message msg) {  
                    // process incoming messages here  
                    super.handleMessage(msg);  
                    switch(msg.what){  
                    case 1:  
                        if(view.getMeasuredHeight() <= getScrollY() + getHeight()) {  
                            if(onScrollListener!=null){  
                                onScrollListener.onBottom();  
                            }  
                              
                        }else if(getScrollY()==0){  
                            if(onScrollListener!=null){  
                                onScrollListener.onTop();  
                            }  
                        }  
                        else{  
                            if(onScrollListener!=null){  
                                onScrollListener.onScroll();  
                            }  
                        }  
                        break;  
                    default:  
                        break;  
                    }  
                }  
            };  
              
        }  
          
          OnTouchListener onTouchListener=new OnTouchListener(){  
      
                @Override  
                public boolean onTouch(View v, MotionEvent event) {  
                    // TODO Auto-generated method stub  
                    switch (event.getAction()) {  
                    case MotionEvent.ACTION_DOWN:  
                        break;  
                    case MotionEvent.ACTION_UP:  
                        if(view!=null&&onScrollListener!=null){  
                            handler.sendMessageDelayed(handler.obtainMessage(1), 200);  
                        }  
                        break;  
      
                    default:  
                        break;  
                    }  
                    return false;  
                }  
                  
            };  
              
            /** 
             * 获得参考的View,主要是为了获得它的MeasuredHeight,然后和滚动条的ScrollY+getHeight作比较。 
             */  
            public void getView(){  
                this.view=getChildAt(0);  
                if(view!=null){  
                    init();  
                }  
            }  
              
            /** 
             * 定义接口 
             * @author admin 
             * 
             */  
            public interface OnScrollListener{  
                void onBottom();  
                void onTop();  
                void onScroll();  
            }  
            private OnScrollListener onScrollListener;  
            public void setOnScrollListener(OnScrollListener onScrollListener){  
                this.onScrollListener=onScrollListener;  
            }  
    } 

    使用方法如下:

    scrollView=(LazyScrollView)findViewById(R.id.scrollView);  
            scrollView.getView();  
            scrollView.setOnScrollListener(new OnScrollListener() {  
                  
                @Override  
                public void onTop() {  
                    // TODO Auto-generated method stub  
                    Log.d(tag,"------滚动到最上方------");  
                }  
                  
                @Override  
                public void onScroll() {  
                    // TODO Auto-generated method stub  
                    Log.d(tag,"没有到最下方,也不是最上方");  
                }  
                  
                @Override  
                public void onBottom() {  
                    // TODO Auto-generated method stub  
                    Log.d(tag,"------滚动到最下方------");  
                }  
            });  
    

    补充一点:

    控制ScrollView滑动到底部,可以使用scrollTo方法,但是相比之下,fullScroll方法:

    scrollView.fullScroll(ScrollView.FOCUS_DOWN);滚动到底部;

    scrollView.fullScroll(ScrollView.FOCUS_UP);滚动到顶部。

    需要注意的是,该方法不能直接被调用,

    因为Android很多函数都是基于消息队列来同步,

    所以需要一部操作,addView完之后,不等于马上就会显示,而是在队列中等待处理,虽然很快,

    但是如果立即调用fullScroll, view可能还没有显示出来,所以会失败应该通过handler在新线程中更新:

    scrollView.post(new Runnable() {  
               @Override  
               public void run() {  
                scrollView.fullScroll(View.FOCUS_DOWN);  
               }  
           });  






    展开全文
  • Android ScrollView监听滑动到顶部和底部,虽然网上很多资料都有说,但是不全,而且有些细节没说清楚   使用场景: 1. 做一些复杂动画的时候,需要动态判断当前的ScrollView是否滚动到底部或者顶部 2...

    Android ScrollView监听滑动到顶部和底部,虽然网上很多资料都有说,但是不全,而且有些细节没说清楚


     

    使用场景:

    1. 做一些复杂动画的时候,需要动态判断当前的ScrollView是否滚动到底部或者顶部

    2. ScrollView滚动到顶部或者底部时主动触发一些操作(典型的就是滚动到底部触发自动加载操作)

     

    两种方式:

    1. onScrollChanged方式,自己计算

    2. onOverScrolled使用系统计算的结果,api >= 9才支持

    可能忽视的细节1:

    如果是手势滑动,上面两种方式都对,但是如果是调用ScrollViewsmoothScrollToscrollTo方法来滚动的话,

    只有onScrollChanged监听对,onOverScrolled监听不对,因为通过代码来滚动话是精确滚动,onOverScrolled方法没处理这种情况

     

    两种方式如何选择?

    一般来说如果系统有实现的东西,就用系统的,我们毕竟是基于Android系统来做开发,别人做的考虑很多适配兼容问题

    所以原则就是系统有就用它的,没有才用我们自己的,具体实现仔细看代码,记得看注释

    如果不考虑smoothScrollTo和scrollTo滚动,上面这个原则就是对的,如果要考虑的话,这里只能使用onScrollChanged

     

    滚动到顶部和底部时对应的计算关系:

     

     

    备注:无padding的情况可以转换为有padding的情况,即tp,bp=0

    mScrollY + H – tp – bp = h ===> mScrollY + H = h 

     

    代码实现,自定义View,可以直接拷贝就可以使用

    下面代码不考虑smoothScrollTo和scrollTo方法的影响,要考虑的话,去掉onOverScrolled方法,去掉onScrollChanged的api版本条件限制即可

    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.ScrollView;
    
    /**
     * 监听ScrollView滚动到顶部或者底部做相关事件拦截
     */
    public class SmartScrollView extends ScrollView {
    
        private boolean isScrolledToTop = true;  // 初始化的时候设置一下值
        private boolean isScrolledToBottom = false;
        public ScanScrollView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        private ISmartScrollChangedListener mSmartScrollChangedListener;
    
        /** 定义监听接口 */
        public interface ISmartScrollChangedListener {
            void onScrolledToBottom();
            void onScrolledToTop();
        }
    
        public void setScanScrollChangedListener(ISmartScrollChangedListener smartScrollChangedListener) {
            mSmartScrollChangedListener = smartScrollChangedListener;
        }
    
        @Override
        protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
            super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
            if (scrollY == 0) {
                isScrolledToTop = clampedY;
                isScrolledToBottom = false;
            } else {
                isScrolledToTop = false;
                isScrolledToBottom = clampedY;
            }
            notifyScrollChangedListeners();
        }
    
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            super.onScrollChanged(l, t, oldl, oldt);
            if (android.os.Build.VERSION.SDK_INT < 9) {  // API 9及之后走onOverScrolled方法监听
                if (getScrollY() == 0) {    // 小心踩坑1: 这里不能是getScrollY() <= 0
                    isScrolledToTop = true;
                    isScrolledToBottom = false;
                } else if (getScrollY() + getHeight() - getPaddingTop()-getPaddingBottom() == getChildAt(0).getHeight()) {
                    // 小心踩坑2: 这里不能是 >= 
             // 小心踩坑3(可能忽视的细节2):这里最容易忽视的就是ScrollView上下的padding 
                    isScrolledToBottom = true;
                    isScrolledToTop = false;
                } else {
                    isScrolledToTop = false;
                    isScrolledToBottom = false;
                }
                notifyScrollChangedListeners();
            }
            // 有时候写代码习惯了,为了兼容一些边界奇葩情况,上面的代码就会写成<=,>=的情况,结果就出bug了
            // 我写的时候写成这样:getScrollY() + getHeight() >= getChildAt(0).getHeight()
            // 结果发现快滑动到底部但是还没到时,会发现上面的条件成立了,导致判断错误
            // 原因:getScrollY()值不是绝对靠谱的,它会超过边界值,但是它自己会恢复正确,导致上面的计算条件不成立
            // 仔细想想也感觉想得通,系统的ScrollView在处理滚动的时候动态计算那个scrollY的时候也会出现超过边界再修正的情况
        }
    
        private void notifyScrollChangedListeners() {
            if (isScrolledToTop) {
                if (mSmartScrollChangedListener != null) {
                    mSmartScrollChangedListener.onScrolledToTop();
                }
            } else if (isScrolledToBottom) {
                if (mSmartScrollChangedListener != null) {
                    mSmartScrollChangedListener.onScrolledToBottom();
                }
            }
        }
    
        public boolean isScrolledToTop() {
            return isScrolledToTop;
        }
    
        public boolean isScrolledToBottom() {
            return isScrolledToBottom;
        }
    }

     

    至此已经介绍完了,为了形象的表示smoothScrollTo和scrollTo方法调用时两种监听方式的结果下面加上log,这里不想看的可以不往下看了

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        if (scrollY == 0) {
            isScrolledToTop = clampedY;
            isScrolledToBottom = false;
            System.out.println("onOverScrolled isScrolledToTop:" + isScrolledToTop);
        } else {
            isScrolledToTop = false;
            isScrolledToBottom = clampedY;
            System.out.println("onOverScrolled isScrolledToBottom:" + isScrolledToBottom);
        }
        notifyScrollChangedListeners();
    }
    
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
       // 这个log可以研究ScrollView的上下padding对结果的影响
        System.out.println("onScrollChanged getScrollY():" + getScrollY() + " t: " + t + " paddingTop: " + getPaddingTop());
        if (getScrollY() == 0) {
            isScrolledToTop = true;
            isScrolledToBottom = false;
            System.out.println("onScrollChanged isScrolledToTop:" + isScrolledToTop);
        } else if (getScrollY() + getHeight() - getPaddingTop() - getPaddingBottom() == getChildAt(0).getHeight()) {
            isScrolledToBottom = true;
            System.out.println("onScrollChanged isScrolledToBottom:" + isScrolledToBottom);
            isScrolledToTop = false;
        } else {
            isScrolledToTop = false;
            isScrolledToBottom = false;
        }
        notifyScrollChangedListeners();
    }

    下面我们看下具体的执行结果:

    1. 手动滑动到底部的情况--->两种方式都监听到了

      

    2. 手动滑动到顶部的情况--->两种方式都监听到了

      

    3. 调用smoothScrollTo(0, Integer.MAX_VALUE)或者scrollTo(0, Integer.MAX_VALUE)滑动到底部的情况

        --->只有onScrollChanged方法监听到滑动到底部

      

    4.  调用smoothScrollTo(0, 0)或者scrollTo(0, 0)滑动到顶部的情况

        --->只有onScrollChanged方法监听到滑动到底部

      

     

    感悟:

      很多细小的知识,我们平时总是因为开发的时候太忙来不及去深究,但是作为开发者我们还是要对技术保持严谨,需要通过自己的实战形成自己的经验,有些很细小的知识可能在关键时候起到意向不到的作用,如果平时注意积累,到时候会事半功倍。

      文章写得不专业,如果读者觉得有用,记得点赞,也欢迎指正。

    展开全文
  • l 代表滑动后当前ScrollView可视界面的左上角在整个ScrollView的X轴中的位置,oldl 也就是滑动前的X轴位置。 t 代表滑动后当前ScrollView可视界面的左上角在整个ScrollView的Y轴上的位置,old t...
  • ScrollView监听滑动到底部、顶部

    千次阅读 2016-12-21 16:42:46
    package ... import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.widget.ScrollView; /** * 作者: kaifang * 时间: 2016/12/19
  • 不需要监听滑动位置,只需要重写ScrollView的onOverScrolled和stopNestedScroll方法就可以了 public class ReadScrollView extends ScrollView{ private int mScrollY = 0; private boolean mClampedY = ...
  • 情景:在一个scrollview里面有多个可以播放视频的item,可以上下滑动,当item可以见的时候视频自动开始播放。 一共3个文件 show code package com.example.beteng.scrollview; import android.os.Handler...
  • (1)做一些复杂动画的时候,需要动态判断当前的ScrollView是否滚动到底部或者顶部。 (2)ScrollView滚动到顶部或者底部时主动触发一些操作(典型的就是滚动到底部触发自动加载操作)。 2. 图解: ...
  • //ScrollView嵌套Listview时候–监听滑动真正停止 //实习期间遇到的小问题,杜酿的时候未一下子找到正确解决; 整理如下//判断滑动停止 scrollview.setOnTouchListener(new OnTouchListener() { private int lastY =...
  • 需要自定义一个ScrollView,去覆写onScrollChanged方法。 @Override protected void onScrollChanged(int l, int t, int oldl, int oldt){ if(t + getHeight() >= ...//ScrollView滑动到底部了 scroll
  • 1. 做一些复杂动画的时候,需要动态判断当前的ScrollView是否滚动到底部或者顶部 2. ScrollView滚动到顶部或者底部时主动触发一些操作(典型的就是滚动到底部触发自动加载操作)   两种方式: 1. ...
  • 主要介绍了Android scrollview监听滑动状态的实例代码,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
  • 小平同志/** * 可以监听ScrollView的上下滑动 ,实现ScrollListener接口,调用setScrollListener(ScrollListener l)方法。 * SCROLL_UP :ScrollView正在向上滑动 * SCROLL_DOWN :ScrollView正在向下滑动 * @author ...
  • 主要介绍了Android开发之ScrollView滑动监听,非常不错,介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
  • ScrollView监听是否滑动到底部

    千次阅读 2017-11-27 20:32:51
    今天遇到个需求ScrollRiew中嵌套RecycleView,RecycleView位于ScrollView的底部,现在要做的是上拉加载更多,本来想直接从RecycleView着手,监听RecycleView的显示的最后一个条目,判断是否添加数据,但是为了解决...
  • [Android] 监听ScrollView惯性滑动事件

    千次阅读 2016-07-17 18:14:38
    [Android] 监听ScrollView惯性滑动事件​ ScrollView本身并没有对外提供监听方法,好在内部有一个方法可以监听滑动事件。所以如果我们想要监听ScrollView的滑动事件,只需要做以下几点即可。 自定义一个ScrollView...
  • ScrollView滑动监听

    千次阅读 2016-03-21 10:38:24
    * 想要咋实际使用中监听ScrollView滑动状态 * 系统其实在api23提供了一个setOnScrollListener方法来监听view的滑动,只是不能向下兼容, * public void setOnScrollChangeListener(OnScrollChangeListener l) {...
  • ScrollView相信对每位Android开发者们来说都不陌生,所以这篇文章给大家主要介绍了Android中ScrollView实现滑动距离监听器的方法,有需要的朋友们可以参考借鉴,下面来一起看看吧。
  • Android ScrollView滑动监听

    万次阅读 2017-12-21 10:18:52
    在Android开发中,很多时候都... 原生的ScrollView并没有实现类似ListView的onScrollListener的接口,在开发中如果需要监听ScrollView滑动状态,比如滑动到顶部(底部),滑动的距离等等,我们需要v4包下的NestedScrol

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,781
精华内容 3,912
关键字:

scrollview监听滑动