简体   繁体   English

ScrollView scrollTo 不起作用

[英]ScrollView scrollTo doesn't work

Same issue as ScrollView .scrollTo not working?ScrollView .scrollTo 不工作相同的问题 Saving ScrollView position on rotation 在旋转时保存 ScrollView 位置

I dynamically add items to scrollView in onCreate.我在 onCreate 中向 scrollView 动态添加项目。 I try the following after all items were added:添加所有项目后,我尝试以下操作:

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

I conclude that there is some event like 'DOM-ready'?我的结论是有一些像“DOM-ready”这样的事件? Are there any callbacks?有回调吗?

You don't need to extend the ScrollView and create your own as per the answer provided by David Daudelin for the this question .您不需要扩展 ScrollView 并根据David Daudelin这个问题提供的答案创建自己的。

Get the ViewTreeObserver of the ScrollView and add an OnGlobalLayoutListener to the ViewTreeObserver .获取ViewTreeObserver中的ScrollView和添加OnGlobalLayoutListenerViewTreeObserver Then call the ScrollView.scrollTo(x,y) method from the onGlobalLayout() method of the OnGlobalLayoutListener .然后调用ScrollView.scrollTo(x,y)从该方法onGlobalLayout()的方法OnGlobalLayoutListener Code:代码:

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

 ViewTreeObserver vto = scrollView.getViewTreeObserver();
 vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
      public void onGlobalLayout() {
           mainScroll.scrollTo(0, 0);
      }
 });

This works for me, replace scrollView.scrollTo() to这对我scrollView.scrollTo() ,将scrollView.scrollTo()替换为

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

I was helped by Vasily Kabunov 's answer in瓦西里·卡布诺夫 (Vasily Kabunov) 的回答帮助了我

ScrollView .scrollTo not working? ScrollView .scrollTo 不起作用? Saving ScrollView position on rotation 在旋转时保存 ScrollView 位置

When you do some changes to a ScrollView, it takes a while for it to replicate the layout changes to the display list and notify the ScrollView that it is, indeed, allowed to scroll to a position.当您对 ScrollView 进行一些更改时,它需要一段时间才能将布局更改复制到显示列表并通知 ScrollView 它确实允许滚动到某个位置。

I've managed to get it working by extending ScrollView with a ScrollView of my own, and adding a method that adds the OnGlobalLayoutListener (as suggested by MH) as needed and scrolls there later.我设法通过使用我自己的 ScrollView 扩展ScrollView并添加一个方法来让它工作,该方法根据需要添加OnGlobalLayoutListener (如 MH 建议)并稍后在那里滚动。 It's a bit more automated than applying it to every case you need it (but then you need to use the new ScrollView ).它比将其应用于您需要的每种情况要自动化一些(但是您需要使用新的ScrollView )。 Anyway, this is the relevant code:无论如何,这是相关的代码:

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

Very useful for me since I wanted to scroll to a given View inside a ScrollView right after having added it.对我来说非常有用,因为我想在添加它后立即滚动到 ScrollView 中的给定视图。

Try this it works: (kotlin)试试这个它有效:(kotlin)

 myScrollView.post(Runnable { myScrollView.scrollTo(0, scrollValue) })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM