首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >同步ScrollView滚动位置-安卓

同步ScrollView滚动位置-安卓
EN

Stack Overflow用户
提问于 2010-10-16 20:41:50
回答 4查看 59.5K关注 0票数 97

我的安卓布局中有2个ScrollViews。我如何同步他们的滚动位置?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-10-17 17:06:26

在ScrollView中有一个方法...

代码语言:javascript
复制
protected void onScrollChanged(int x, int y, int oldx, int oldy)

不幸的是,谷歌从来没有想过我们需要访问它,这就是为什么他们将它设置为受保护的,并且没有添加一个"setOnScrollChangedListener“钩子。因此,我们必须为自己做这件事。

首先,我们需要一个接口。

代码语言:javascript
复制
package com.test;

public interface ScrollViewListener {

    void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);

}

然后,我们需要重写ScrollView类,以提供ScrollViewListener挂钩。

代码语言:javascript
复制
package com.test;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;

public class ObservableScrollView extends ScrollView {

    private ScrollViewListener scrollViewListener = null;

    public ObservableScrollView(Context context) {
        super(context);
    }

    public ObservableScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public ObservableScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldx, int oldy) {
        super.onScrollChanged(x, y, oldx, oldy);
        if(scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
        }
    }

}

我们应该在布局中指定这个新的ObservableScrollView类,而不是现有的ScrollView标记。

代码语言:javascript
复制
<com.test.ObservableScrollView
    android:id="@+id/scrollview1"
    ... >

    ...

</com.test.ObservableScrollView>

最后,我们将所有这些放在布局类中。

代码语言:javascript
复制
package com.test;

import android.app.Activity;
import android.os.Bundle;

public class Q3948934 extends Activity implements ScrollViewListener {

    private ObservableScrollView scrollView1 = null;
    private ObservableScrollView scrollView2 = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.q3948934);

        scrollView1 = (ObservableScrollView) findViewById(R.id.scrollview1);
        scrollView1.setScrollViewListener(this);
        scrollView2 = (ObservableScrollView) findViewById(R.id.scrollview2);
        scrollView2.setScrollViewListener(this);
    }

    public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
        if(scrollView == scrollView1) {
            scrollView2.scrollTo(x, y);
        } else if(scrollView == scrollView2) {
            scrollView1.scrollTo(x, y);
        }
    }

}

scrollTo()代码会为我们处理任何循环条件,所以我们不需要担心这一点。唯一的警告是,这个解决方案不能保证在未来的Android版本中工作,因为我们覆盖了一个受保护的方法。

票数 292
EN

Stack Overflow用户

发布于 2012-12-20 01:06:54

安迪的解决方案的一个改进:在他的代码中,他使用了scrollTo,问题是,如果你向一个方向抛出一个滚动视图,然后向另一个方向抛出另一个滚动视图,你会注意到第一个滚动视图不会停止他之前的抛出移动。

这是因为scrollView使用computeScroll()来做它的手势,并且它与scrollTo发生了冲突。

为了防止这种情况,只需这样对onScrollChanged进行编程:

代码语言:javascript
复制
    public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
    if(interceptScroll){
        interceptScroll=false;
        if(scrollView == scrollView1) {
            scrollView2.onOverScrolled(x,y,true,true);
        } else if(scrollView == scrollView2) {
            scrollView1.onOverScrolled(x,y,true,true);
        }
        interceptScroll=true;
    }
}

对于interceptScroll,静态布尔值被初始化为true。(这有助于避免ScrollChanged上的无限循环)

onOverScrolled是我发现的唯一一个可以用来阻止scrollView抛出的函数(但我可能错过了其他函数!)

要访问此功能(受保护),您必须将其添加到您的ObservableScrollViewer中

代码语言:javascript
复制
public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
    super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
}
票数 12
EN

Stack Overflow用户

发布于 2012-03-14 02:34:29

为什么不在你的活动中实现OnTouchListener呢?然后覆盖onTouch方法,然后获取第一个ScrollViewOne.getScrollY()的滚动位置并更新ScrollViewTwo.scrollTo(0, ScrollViewOne.getScrollY());

只是另一个想法。:)

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3948934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档