Android scrollview onScrollChanged
我在滚动视图中的文本视图中有固定内容。当用户滚动到某个位置时,我想启动一个活动或触发一个Android scrollview onScrollChanged,android,android-scrollview,onscrollchanged,Android,Android Scrollview,Onscrollchanged,我在滚动视图中的文本视图中有固定内容。当用户滚动到某个位置时,我想启动一个活动或触发一个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 xmln
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
以查找滚动视图的位置
我已经找到了答案,有没有比在我发布的链接中声明一个界面、覆盖滚动视图等更简单的解决方案
ScrollView不提供滚动事件的侦听器,甚至不提供检查用户滚动到底有多远的方法,因此您必须按照链接的建议进行操作。实际上有一种方法可以知道用户滚动到底有多远。ScrollView中的getScrollY()方法告诉您。有一种比子类化
ScrollView
简单得多的方法。ScrollView
的ViewTreeObserver
对象可用于侦听滚动
由于ViewTreeObserver
对象可能在ScrollView
的生命周期内发生变化,因此我们需要在ScrollView
上注册一个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;
}
});
这个问题很老了,但万一有人(像我一样)路过: 从API 23开始,Android的
视图有一个OnScrollChangeListener
和
支持库中的还支持在API级别之前设置滚动侦听器。据我所知,NestedScrollView
可以毫无问题地替代普通的ScrollView
。我扩展了ScrollView。也许会有帮助
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);
}
}
MyScroll类扩展了ScrollView{
布尔onTop=真;
@凌驾
CrollChanged上的受保护无效(int l、int t、int oldl、int oldt){
//Log.d(标记“scroll changed:”+this.getTop()+“”+t);
如果(t只需使用NestedScroll
和NestedScroll.setOnScrollChangeListener()
就可以了,这有助于在Android中监听任意视图的滚动事件。在内部,该组件在使用旧Android API的设备上添加ViewTreeObserver滚动事件监听器(类似于Shubhadeep Chaudhuri的回答中提出的建议)并在具有新Android API(API级别23+)的设备上查看滚动事件侦听器。从API 23 Android M开始,您可以使用OnScrollChangeListener
scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
//work with parameters
}
});
NestedScrollView与android.widget.ScrollView类似,但它支持在新版本和旧版本的android上同时充当嵌套滚动父级和子级
第一个-使用NestedScrollView绑定代替ScrollView
第二个-设置滚动侦听器,如下所示,通过示例检测headerView的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);
}
}
});
您可以使用此触发器显示Toast或开始活动
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
// do something when Scroll
}
});
您可以使用此代码检测是否向上或向下滚动
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;
}
});
scrollView.getViewTreeObserver().addOnScrollChangedListener(新的ViewTreeObserver.OnScrollChangedListener(){
int lastcoll=0;
@凌驾
public void onScrollChanged(){
int scrollY=scrollView.getScrollY();//对于scrollView区域,请使用getScrollX()
如果(滚动>上次滚动){
Log.e(“滚动”、“向下滚动”+滚动);
}else if(滚动<上次滚动){
Log.e(“滚动”、“向上滚动”+滚动);
}
lastScroll=滚动;
}
});
没有,根据这一点:我在公司的一个项目中使用了这个解决方案。我在这里发布一些东西之前测试了所有东西。也许你也应该这样做?对不起,误读了这个问题。它适用于滚动视图
,但不适用于列表视图
或网格视图
。有一个可以覆盖的CrollChanged方法。比如ise getScrollX,getScrollY可以使用。这个答案现在似乎无效。从API 23(M)开始,有一个名为“OnScrollChangeListener”的监听器scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener(){@Override public void onScrollChange(视图v,int scrollX,int scrollY,int oldScrollX,int oldScrollY){//使用参数}})@S.D.NChanakaFernando还应该注意的是,当涉及到滚动时,它仍然没有提供一个特定的内置解决方案。例如,如果你想检测滚动的结束,你必须手动使用onScrollChangeListener
,这是非常烦人的。下面是一些任何人在这个问题上绊倒的建议问题:你可以使用它,这并不一定比子类化ScrollView
容易。实际上,它包含更多的代码。如果你子类化,你可以覆盖onScrollChanged
方法。我尝试了这个方法,它似乎为相同的scroll Y值触发了20次或更多的事件。这似乎并不理想。嗯……这是一个巨大的问题使用此代码!此问题会导致错误,如@RandomEngy comment中的错误。因此我不知道为什么它的投票率如此之高。它会在SCROLL上的每个触摸事件中添加此侦听器。因此,基本上,如果您单击滚动20次,将导致20次调用侦听器。侦听器应该只添加一次。例如:scrollView.getViewTreeObserver().addOnScrollChangedListener(新的ViewTreeObserver.OnScrollChangedListener(){@Override public void onScrollChanged(){//do stuff}}});
。不在触控方式内,甚至更糟的是,它可能会添加至少40个监听器(每次点击至少会触控和触控)在这个例子中,我使用了OnTouchListener
,因为上面说“返回的ViewTreeObserver观察器不保证在该视图的生命周期内保持有效”。我编辑了答案,因此如果ViewTreeObserver
不再活动,那么对它的回调