情况:
在表行的两个水平滚动视图中,每一个都有两个滚动视图。
目标:
当我触摸拖动其中一个ScrollView时,另一个ScrollView必须同样滚动。例如,如果我在左滚动视图中有一个姓名列表,在右滚动视图中有相应的电话号码,滚动一个滚动视图不应该破坏姓名和电话号码之间的原始边界。
它可以由ontouchevent实现吗?如果是,我应该如何实现(在两个或一个scrollview上)?
请帮帮我安卓大师!

最佳答案

我有一个简单的解决方法:
子类化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;
    }
}

创建一个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;
    }
}

创建自定义ScrollViews并设置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);
}

08-26 04:34