7

与 ScrollView相同的问题.scrollTo 不起作用?在旋转时保存 ScrollView 位置

我在 onCreate 中动态地将项目添加到 scrollView。添加所有项目后,我尝试以下操作:

    // no effect
    ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);

    // no effect
    ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);
    mainScroll.post(new Runnable() {
        public void run(){
            ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);
            mainScroll.scrollTo(0, 0);
        } 
    });

    // works like a charm
    ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);
    mainScroll.postDelayed(new Runnable() {
        public void run(){
            ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);
            mainScroll.scrollTo(0, 0);
        } 
    }, 30);

我得出结论,有一些事件,如“DOM-ready”?有回调吗?

4

4 回答 4

19

您不需要扩展 ScrollView 并根据David Daudelinthis question提供的答案创建自己的。

获取 的ViewTreeObserver并将ScrollView一个添加OnGlobalLayoutListenerViewTreeObserver. 然后ScrollView.scrollTo(x,y)从 的onGlobalLayout()方法中调用方法OnGlobalLayoutListener。代码:

 ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);

 ViewTreeObserver vto = scrollView.getViewTreeObserver();
 vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
      public void onGlobalLayout() {
           mainScroll.scrollTo(0, 0);
      }
 });
于 2013-09-21T08:02:00.447 回答
7

这对我有用,替换scrollView.scrollTo()

     scrollView.post(new Runnable() {
        @Override
        public void run() {
            scrollView.scrollTo(0, ScrollViewYPosition);//0 is x position
        }
    });

Vasily Kabunov 的回答帮助了我

ScrollView .scrollTo 不工作?在旋转时保存 ScrollView 位置

于 2018-03-09T08:19:30.670 回答
1

当您对 ScrollView 进行一些更改时,它需要一段时间才能将布局更改复制到显示列表并通知 ScrollView 它确实可以滚动到某个位置。

我设法通过ScrollView使用我自己的 ScrollView 进行扩展,并添加一个OnGlobalLayoutListener根据需要添加(如 MH 建议的)并稍后滚动到那里的方法来使其工作。它比将其应用于您需要的每个案例要自动化一些(但是您需要使用 new ScrollView)。无论如何,这是相关的代码:

public class ZScrollView extends ScrollView {

    // Properties
    private int desiredScrollX = -1;
    private int desiredScrollY = -1;
    private OnGlobalLayoutListener gol;

    // ================================================================================================================
    // CONSTRUCTOR ----------------------------------------------------------------------------------------------------

    public ZScrollView(Context __context) {
        super(__context);
    }

    public ZScrollView(Context __context, AttributeSet __attrs) {
        super(__context, __attrs);
    }

    public ZScrollView(Context __context, AttributeSet __attrs, int __defStyle) {
        super(__context, __attrs, __defStyle);
    }

    // ================================================================================================================
    // PUBLIC INTERFACE -----------------------------------------------------------------------------------------------

    public void scrollToWithGuarantees(int __x, int __y) {
        // REALLY Scrolls to a position
        // When adding items to a scrollView, you can't immediately scroll to it - it takes a while
        // for the new addition to cycle back and update the scrollView's max scroll... so we have
        // to wait and re-set as necessary

        scrollTo(__x, __y);

        desiredScrollX = -1;
        desiredScrollY = -1;

        if (getScrollX() != __x || getScrollY() != __y) {
            // Didn't scroll properly: will create an event to try scrolling again later

            if (getScrollX() != __x) desiredScrollX = __x;
            if (getScrollY() != __y) desiredScrollY = __y;

            if (gol == null) {
                gol = new OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        int nx = desiredScrollX == -1 ? getScrollX() : desiredScrollX;
                        int ny = desiredScrollY == -1 ? getScrollY() : desiredScrollY;
                        desiredScrollX = -1;
                        desiredScrollY = -1;
                        scrollTo(nx, ny);
                    }
                };

                getViewTreeObserver().addOnGlobalLayoutListener(gol);
            }
        }
    }
}

对我来说非常有用,因为我想在添加后立即滚动到 ScrollView 内的给定视图。

于 2012-11-30T22:06:36.843 回答
0

试试这个它的工作原理:(kotlin)

             myScrollView.post(Runnable {
                 myScrollView.scrollTo(0, scrollValue)
             })
于 2020-03-12T05:42:19.383 回答