为了账号安全,请及时绑定邮箱和手机立即绑定

同步滚动视图滚动位置-Android

同步滚动视图滚动位置-Android

人到中年有点甜 2019-06-27 17:01:25
同步滚动视图滚动位置-Android我有两个ScrollView在我的Android布局。如何同步他们的滚动位置?
查看完整描述

3 回答

?
元芳怎么了

TA贡献1798条经验 获得超7个赞

在ScrollView中有一种方法.。

protected void onScrollChanged(int x, int y, int oldx, int oldy)

不幸的是,Google从未想过我们需要访问它,这就是为什么他们让它受到保护,并且没有添加一个“setOnScrollChangedListener”钩子。所以我们必须为自己做这件事。

首先我们需要一个接口。

package com.test;public interface ScrollViewListener {

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

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

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);
        }
    }}

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

<com.test.ObservableScrollView
    android:id="@+id/scrollview1"
    ... >

    ...</com.test.ObservableScrollView>

最后,我们将其放在布局类中。

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的未来版本中工作,因为我们正在覆盖一个受保护的方法。


查看完整回答
反对 回复 2019-06-27
?
慕哥6287543

TA贡献1831条经验 获得超10个赞

Andy的解决方案的一个改进:在他的代码中,他使用了滚动到,问题是,如果你把一个滚动视图扔向一个方向,然后把另一个滚动视图扔向另一个方向,你会注意到第一个滚动视图并没有停止他以前的快速移动。

这是因为SCROLLView使用ComputeScroll()来执行抛出的手势,并且它与滚动到冲突。

为了防止这种情况,只需按以下方式对onScrollChanged进行编程:

    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;
    }}

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

OnOverScrolled是我发现的唯一可以用来阻止滚动视图抛出的函数(但可能还有其他函数我错过了!)

为了访问这个函数(它是受保护的),您必须将它添加到您的观测者ScrollViewer中。

public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
    super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);}


查看完整回答
反对 回复 2019-06-27
?
忽然笑

TA贡献1806条经验 获得超5个赞

为什么不直接实现OnTouchListener在你的活动中。然后重写OnTouch方法,然后获得第一个滚动位置ScrollViewOne.getScrollY()和更新ScrollViewTwo.scrollTo(0, ScrollViewOne.getScrollY());

只是另一个想法.。*)


查看完整回答
反对 回复 2019-06-27
  • 3 回答
  • 0 关注
  • 412 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信