首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步两ScrollView

同步两ScrollView
EN

Stack Overflow用户
提问于 2010-08-19 23:35:43
回答 2查看 7.9K关注 0票数 12

情景:--在两个TableRow的HorizontalScrollView中各有两个ScrollView。

目标:当我触摸时,拖动ScrollView的一个,另一个ScrollView必须滚动同样多。例如,如果左ScrollView上有一个名称列表,而右侧ScrollView中有相应的电话号码,则滚动一个ScrollView不应该破坏名称和电话号码之间的原始界限。

它能用onTouchEvent实现吗?如果是这样的话,我应该如何实现这一点(无论是在ScrollView上还是在其中一个)?

请帮帮我,机器人大师!

EN

回答 2

Stack Overflow用户

发布于 2011-03-02 15:56:13

我有一个对我有用的简单解决方案:

  • 子类和重写它们的onScrollChanged事件,以便在滚动更改时更新ScrollManager

公共接口ScrollNotifier {公共无效setScrollListener(ScrollListener scrollListener);公共ScrollListener getScrollListener();}公共类SyncedScrollView扩展ScrollView实现ScrollNotifier {//.私有scrollListener ScrollListener = null;@重写受保护的无效onScrollChanged(int l,int t,int oldl,int oldt) { super.onScrollChanged(l,t,oldl,oldt);if (scrollListener != null) scrollListener.onScrollChanged(this,l,t,oldl,oldt);} @Override void setScrollListener(ScrollListener scrollListener) { this.scrollListener = scrollListener;}@重写公共ScrollListener getScrollListener() {返回scrollListener;}

  • 创建协调多个参与者滚动的ScrollManager

公共接口ScrollListener { void onScrollChanged(View syncedScrollView,int l,int t,int oldl,int oldt);}公共类ScrollManager实现ScrollListener {私有静态最终int SCROLL_HORIZONTAL = 1;私有静态最终int SCROLL_VERTICAL = 2;私有ArrayList客户端=新ArrayList(4);私有易失布尔isSyncing = false;私有int scrollType = SCROLL_HORIZONTAL;公共虚空addScrollClient(ScrollNotifier client) {clients.add(客户端);client.setScrollListener(此);} // TODO修正了对所有视图的依赖关系,这些视图具有相同的水平/垂直//维度@覆盖公共无效onScrollChanged(查看发件人、int l、int t、int oldl、int oldt) { //避免通知,而滚动条则同步如果( isSyncing ) {返回;}isSyncing= true;//记住滚动类型if (l != oldl) { scrollType = SCROLL_HORIZONTAL;}oldl if (t != oldt) { scrollType = SCROLL_VERTICAL;}scrollType{ //不确定为什么会发生isSyncing = false;返回;} //更新(ScrollNotifier客户端:客户端){查看视图=(视图)客户端;//不更新发送方如果(查看==发件人){继续;} //只滚动相关视图// TODO添加对水平ListViews的支持--目前,当ListView被水平滚动时会发生奇怪的事情,如果((scrollType == SCROLL_HORIZONTAL & view instanceof HorizontalScrollView) )x( (scrollType == SCROLL_VERTICAL &view.scrollTo)){ view.scrollTo(l,t);}} isSyncing = false;}

  • 创建自定义ScrollView,并将ScrollManager设置为两者的通知

私有setupScrolling() { ScrollNotifier视图;scrollManager ScrollManager =新ScrollManager();//时间线水平滚动视图= (ScrollNotifier) findViewById(R.id.epgtimeline_container);scrollManager.addScrollClient(视图);//服务垂直滚动视图= (ScrollNotifier) findViewById(R.id.epgservices_container);scrollManager.addScrollClient(视图);//内容区域滚动视图= (ScrollNotifier) findViewById(R.id.epgevents_container_inner);scrollManager.addScrollClient(视图);视图= (ScrollNotifier) findViewById(R.id.epgevents_container_outer);scrollManager.addScrollClient(视图);}

票数 19
EN

Stack Overflow用户

发布于 2016-11-25 11:21:12

感谢andig给了如此伟大的synching scrollview solution

但是,在抛出时,两个滚动视图之间几乎没有一点延迟。

因此,我在这里编写扩展解决方案,以消除两个滚动视图之间的滞后。

我刚刚使用了OverScroller类,并在SyncedScrollView中手动处理了have事件。

您必须将SyncedScrollView替换为下面的代码。使用andig's solution中的其他类

代码语言:javascript
复制
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.OverScroller;
import android.widget.ScrollView;

/**
 * Created by mitul.varmora on 11/7/2016.
 * SyncedScrollView
 * https://stackoverflow.com/questions/3527119/sync-two-scrollview
 */
public class SyncedScrollView extends ScrollView implements ScrollNotifier {

    private ScrollListener scrollListener = null;

    private OverScroller scroller;
    private Runnable scrollerTaskRunnable;

    public SyncedScrollView(Context context) {
        super(context);
        init();
    }

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

    public SyncedScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {

        scroller = new OverScroller(getContext());
        scrollerTaskRunnable = new Runnable() {
            @Override
            public void run() {
                scroller.computeScrollOffset();

                smoothScrollTo(0, scroller.getCurrY());

                if (!scroller.isFinished()) {
                    SyncedScrollView.this.post(this);
                } else {
                    //deceleration ends here, do your code
                    ViewCompat.postInvalidateOnAnimation(SyncedScrollView.this);
                }
            }
        };
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (scrollListener != null)
            scrollListener.onScrollChanged(this, l, t, oldl, oldt);
    }

    @Override
    public ScrollListener getScrollListener() {
        return scrollListener;
    }

    @Override
    public void setScrollListener(ScrollListener scrollListener) {
        this.scrollListener = scrollListener;
    }

    @Override
    public void fling(int velocityY) {

        scroller.forceFinished(true);
        scroller.fling(getScrollX(), getScrollY(), 0, velocityY, 0, 0, 0, getChildAt(0).getHeight());
        post(scrollerTaskRunnable);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
//        return super.onTouchEvent(ev);
        boolean eventConsumed = super.onTouchEvent(ev);
        if (eventConsumed && ev.getAction() == MotionEvent.ACTION_UP) {
            if (scroller.isFinished()) {
                //do your code
            }
        }
        return eventConsumed;
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3527119

复制
相关文章

相似问题

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