同步两个ScrollView

Yoo*_*ung 8 android android-widget

情况: 我在TableRow的两个Horizo​​ntalScrollView中分别有两个ScrollView.

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

可以通过onTouchEvent实现吗?如果是这样,我应该如何实现它(在两个或一个ScrollView上)?

请帮帮我安卓大师!

and*_*dig 16

我有一个适合我的简单解决方案:

  • 在滚动更改时,子类同时ScrollViews并覆盖其onScrollChanged事件以进行更新ScrollManager:

    public interface ScrollNotifier {   
        public void setScrollListener(ScrollListener scrollListener);
    
        public ScrollListener getScrollListener();
    }
    
    public class SyncedScrollView extends ScrollView implements ScrollNotifier {
    
        //...
    
        private ScrollListener scrollListener = null;
    
        @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 void setScrollListener(ScrollListener scrollListener) {
            this.scrollListener = scrollListener;
        }
        @Override
        public ScrollListener getScrollListener() {
            return scrollListener;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建一个ScrollManager协调多个参与者滚动的类

    public interface ScrollListener {
        void onScrollChanged(View syncedScrollView, int l, int t, int oldl,
            int oldt);
    }
    
    public class ScrollManager implements ScrollListener {
        private static final int SCROLL_HORIZONTAL = 1;
        private static final int SCROLL_VERTICAL = 2;
    
        private ArrayList<ScrollNotifier> clients = new ArrayList<ScrollNotifier>(4);
    
        private volatile boolean isSyncing = false;
        private int scrollType = SCROLL_HORIZONTAL;
    
        public void addScrollClient(ScrollNotifier client) {
            clients.add(client);
            client.setScrollListener(this);
        }
    
        // TODO fix dependency on all views being of equal horizontal/ vertical
        // dimensions
        @Override
        public void onScrollChanged(View sender, int l, int t, int oldl, int oldt) {
            // avoid notifications while scroll bars are being synchronized
            if (isSyncing) {
                return;
            }
    
            isSyncing = true;
    
            // remember scroll type
            if (l != oldl) {
                scrollType = SCROLL_HORIZONTAL;
            } else if (t != oldt) {
                scrollType = SCROLL_VERTICAL;
            } else {
                // not sure why this should happen
                isSyncing = false;
                return;
            }
    
            // update clients
            for (ScrollNotifier client : clients) {
                View view = (View) client;
                // don't update sender
                if (view == sender) {
                    continue;
                }
    
                // scroll relevant views only
                // TODO Add support for horizontal ListViews - currently weird things happen when ListView is being scrolled horizontally
                if ((scrollType == SCROLL_HORIZONTAL && view instanceof HorizontalScrollView)
                        || (scrollType == SCROLL_VERTICAL && view instanceof ScrollView)
                        || (scrollType == SCROLL_VERTICAL && view instanceof ListView)) {
                    view.scrollTo(l, t);
                }
            }
    
            isSyncing = false;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建自定义ScrollViews并ScrollManager在两者上设置for通知

    private void setupScrolling() {
        ScrollNotifier view;
        ScrollManager scrollManager = new ScrollManager();
    
        // timeline horizontal scroller
        view = (ScrollNotifier) findViewById(R.id.epgtimeline_container);
        scrollManager.addScrollClient(view);
    
        // services vertical scroller
        view = (ScrollNotifier) findViewById(R.id.epgservices_container);
        scrollManager.addScrollClient(view);
    
        // content area scrollers
        view = (ScrollNotifier) findViewById(R.id.epgevents_container_inner);
        scrollManager.addScrollClient(view);
        view = (ScrollNotifier) findViewById(R.id.epgevents_container_outer);
        scrollManager.addScrollClient(view);
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 极好的答案,我在这两天里一直在尝试使用 onTouchEvent 并通过那个低谷。我终于开始工作了,但它只能以一种方式工作......这解决了我所有的问题......;-)......几乎所有我的问题哈哈 (2认同)