android - 同步两个 ScrollView

标签 android android-widget

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

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

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

请帮帮我 Android 高手!

最佳答案

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

  • 子类化 ScrollView 并覆盖它们的 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;
        }
    }
    
  • 创建一个 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;
        }
    }
    
  • 创建自定义 ScrollView 并设置 ScrollManager 以在两者上进行通知

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

关于android - 同步两个 ScrollView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3527119/

相关文章:

java - 如何在android中将ListActivities添加到ViewPager中?

php - 从php数据库读取数据到android应用程序

android - 以编程方式在小部件上设置 ImageView 宽度和高度

Android:带有链接链接的可点击 TextView

Android AppWidget onUpdate 并不总是更新小部件

android - 小部件存储数据 android

android - Android Java代码中 'instanceof'的影响

java - 将 ByteInputStream 分配给 InputStream,保持绑定(bind)到终端仿真器

android - SQLite 数据库最初是什么时候在 Android 中创建的?

android - 小部件图标下方的 Android AppWidget 标题