代码之家  ›  专栏  ›  技术社区  ›  SteD

Android滚动视图onScrollChanged

  •  22
  • SteD  · 技术社区  · 14 年前

    我在滚动视图中的文本视图中有一个固定内容。当用户滚动到某个位置时,我想启动一个活动或触发 Toast .

    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent" android:layout_height="fill_parent"
     android:id="@+id/scroller">
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical" android:layout_width="fill_parent"
      android:layout_height="fill_parent">
      <TextView android:layout_width="fill_parent" android:id="@+id/story"
       android:layout_height="wrap_content" android:text="@string/lorem"
       android:gravity="fill" />
     </LinearLayout>
    </ScrollView>
    

    我的问题是实现受保护的方法 onScrollChanged 找出滚动视图的位置。

    我发现了 this 答案是,有没有一个更简单的解决方案,而不是像我发布的链接那样声明一个接口、过度使用scrollview等?

    10 回复  |  直到 7 年前
        1
  •  13
  •   Computerish    14 年前

    不。

    ScrollView不提供scroll事件的监听器,甚至不提供检查用户向下滚动了多远的方法,因此必须按照链接的建议进行操作。

        2
  •  48
  •   timemanx    10 年前

    有一种比子类化 ScrollView . 这个 ViewTreeObserver 目标 卷轴视图 可以用来听卷轴。

    自从 ViewTreeObserver视图 对象可能在 卷轴视图 ,我们需要注册一个 OnTouchListener 卷轴视图 为了得到它 ViewTreeObserver视图 在滚动的时候。

    final ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = new
                               ViewTreeObserver.OnScrollChangedListener() {
    
        @Override
        public void onScrollChanged() {
            //do stuff here 
        }
    };
    
    final ScrollView scrollView = (ScrollView) findViewById(R.id.scroller);
    scrollView.setOnTouchListener(new View.OnTouchListener() {
        private ViewTreeObserver observer;
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (observer == null) {
                observer = scrollView.getViewTreeObserver();
                observer.addOnScrollChangedListener(onScrollChangedListener);
            }
            else if (!observer.isAlive()) {
                observer.removeOnScrollChangedListener(onScrollChangedListener);
                observer = scrollView.getViewTreeObserver();
                observer.addOnScrollChangedListener(onScrollChangedListener);
            }
    
            return false;
        }
    });
    
        3
  •  9
  •   Lovis    8 年前

    这个问题已经很老了,但万一有人(像我一样)来问你:

    API 23标准 ,安卓系统 View 有一个 OnScrollChangeListener 以及 matching setter .

    这个 NestedScrollView 从支持库中还支持在API级别之前设置滚动侦听器。据我所知, NestedScrollView 可以用来代替普通的 ScrollView 没有任何问题。

        4
  •  8
  •   zango123    13 年前

    实际上,有一种方法可以知道用户滚动了多远。ScrollView中的getScrollY()方法告诉您这一点。

        5
  •  2
  •   Gogi Bobina    9 年前

    我扩展了我的滚动视图。 This link 可能有帮助。

    class MyScroll extends ScrollView {
        boolean onTop=true;
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            //Log.d(TAG, "scroll changed: " + this.getTop() + " "+t);
            if(t <= 0){
                onTop = true;
                //Log.d(TAG, "scroll top: " + t);
                super.onScrollChanged(l, t, oldl, oldt);
                return;
                // reaches the top end
            }
            onTop = false;
    
            View view = (View) getChildAt(getChildCount()-1);
            int diff = (view.getBottom()-(getHeight()+getScrollY()+view.getTop()));// Calculate the scrolldiff
            if( diff <= 0 ){
                // if diff is zero, then the bottom has been reached
            }
            super.onScrollChanged(l, t, oldl, oldt);
        }
    }
    
        6
  •  1
  •   Javi AP    7 年前

    NestedScrollView与android.widget.ScrollView类似,但它支持在新版本和旧版本的android上同时充当嵌套的滚动父级和子级。

    第一-使用嵌套的ScrollView绑定而不是ScrollView

    第二集滚动侦听器,像这样,通过示例检测轴Y移动的头视图。

        nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
    
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                Log.d(TAG, "onScrollChangeForY - scrollY: " + scrollY + " oldScrollY: " + oldScrollY);
    
                int MOVE = -1, SCROLL_UP = 0, SCROLL_DOWN = 1;
                float initialPositionY = headerView.getY();
    
                MOVE = scrollY > oldScrollY ? SCROLL_UP : SCROLL_DOWN;
    
                if (MOVE == SCROLL_UP) {
    
                    int incrementY = scrollY - oldScrollY;
    
                    headerView.setY(initialPositionY - incrementY);
    
                } else {
    
                    int incrementY = oldScrollY - scrollY;
    
                    headerView.setY(initialPositionY + incrementY);
                }
            }
        });
    
        7
  •  1
  •   Mahmoud Abu Alheja sbzoom    5 年前

    您可以使用此代码检测是否向上或向下滚动

    scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
                int lastScroll=0;
                @Override
                public void onScrollChanged() {
                    int scrollY = scrollView.getScrollY(); // For ScrollView herzontial use getScrollX()
    
                    if (scrollY > lastScroll ) {
                        Log.e("scroll","down scroll"+scrollY);
                    } else if (scrollY < lastScroll ) {
                        Log.e("scroll","up scroll"+scrollY);
                    }
                    lastScroll=scrollY;
                }
            });
    
        8
  •  0
  •   Denis    8 年前

    ready for use component ,这有助于监听Android中任意视图的滚动事件。在内部,该组件在具有旧Android API(类似于Shubhadeep Chaudhuri的答案中提出的)的设备上添加ViewTreeObserver scroll events listener,并在具有新Android API(API级别23+)的设备上添加ViewTreeObserver scroll events listener。

        9
  •  0
  •   Lavekush Agrawal rekire    7 年前

    只是使用 NestedScroll NestedScroll.setOnScrollChangeListener() .

        10
  •  0
  •   yousef    7 年前

    您可以使用此触发器显示Toast或开始活动

     scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
            @Override
            public void onScrollChanged() {
                 // do something when Scroll  
            }
        });
    
        11
  •  -1
  •   Chanaka Fernando    7 年前

    从API23Android M开始,您可以使用OnScrollChangeListener。

     scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                //work with parameters
            }
        });