Android ScrollView在更改子元素的可见性后跳跃向上。

huangapple go评论143阅读模式
英文:

Android ScrollView jumps up after changing child element visibility

问题

我有一个包含了一些默认设置为View.GONE的元素的ScrollView。问题是,每当这些元素的可见性从View.GONE更改为View.VISIBLE时,滚动条会向上跳跃,就像第二张图片所示:

链接:https://i.stack.imgur.com/F2aKS.png

红色框表示当前滚动位置,蓝色矩形是可见性更改的元素,绿色矩形是一些元素(例如按钮),我可以参考它。我希望我的ScrollView的工作方式如第三张图片所示。如果屏幕上有绿色按钮,那么在显示新元素(蓝色元素)之后,绿色按钮也应该在屏幕上可见。有什么方法可以实现这个效果吗?

英文:

I have a ScrollView that contains elements with visibility set to View.GONE by default. The problem is that whenever this visibility changes from View.GONE to View.VISIBLE, scroll jumps up as it is shown on second picture:
https://i.stack.imgur.com/F2aKS.png

The red box represents current scroll position, blue rectangle is an element which visibility is changed, and green rectangle is some element (for example button) that I can refer to. I want my ScrollView to work as it is shown on third picture. If green button is on the screen, it should also be visible on screen after displaying new element (the blue one) above it. Any ideas how can I achieve it?

答案1

得分: 2

好的,下面是您要翻译的内容:

好的,它的行为与预期完全一致 - 滚动位置位于距顶部约200像素的位置,并且当新项目更改其可见性时,这不会改变。

您应该自行滚动到适当的(新的)位置,使用scrollTo方法 - 测量此新“View”的高度,并调用scrollView.scrollTo(0, currentScrollY + heightOfNewView)

请注意,当您更改可见性时,不能在上面的scrollTo语句之后立即调用上述内容,您必须等待此“View”被测量和绘制。因此,您应该在例如以下情况下调用scrollTo

visibilityChangedView.setVisibility(View.VISIBLE);
visibilityChangedView.post(new Runnable() {

    // 这将在visibilityChangedView没有待处理任务时被调用,
    // 但我们刚刚改变了可见性,
    // 所以首先将对视图进行测量和绘制,
    // 然后将调用下面的run()方法

    @Override
    public void run() {
        int heightOfNewView = visibilityChangedView.getMeasuredHeight();
        int currentScrollY = scrollView.getScrollY();
        scrollView.scrollTo(0, currentScrollY + heightOfNewView);
    }
});

有可能此自动滚动对用户可见,类似于快速跳转 - 首先整个视图将绘制为#2,经过一帧或一瞬间后,它将以新位置重新绘制,类似于#3。我不了解您的内容是如何构建的(ScrollView中的其他子项),但我怀疑这应该是带有适当AdapterRecyclerView或至少是ListView,而不是具有固定布局的ScrollView

英文:

well, it behaves exacly as it should - scroll position is on e.g. 200px from top and this doesn't change when new item changes its visibility

you should scroll by yourself to proper (new) point, use scrollTo method - measure height of this new View and call scrollView.scrollTo(0, currentScrollY + heightOfNewView)

be aware that when you change visibility then you can't call above scrollTo just one line below, you have to wait for this View being measured and drawn. so you should call scrollTo in e.g.

visibilityChangedView.setVisibility(View.VISIBLE);
visibilityChangedView.post(new Runnable() {

        // this will be called when visibilityChangedView won't have
        // any pending tasks to do, but we just changed visibility,
        // so at first view will be measured and drawn, after that
        // below run() method will be called

        @Override
        public void run() {
            int heightOfNewView = visibilityChangedView.getMeasuredHeight();
            int currentScrollY = scrollView.getScrollY();
            scrollView.scrollTo(0, currentScrollY + heightOfNewView);
        }
);

there is a chance that this automatic scroll will be visible to user as quick jump - at first whole view will be drawn as #2 and after split second/one frame it will redraw at new position like #3. I don't know how your content is built (rest of childs in Scrollview), but I suspect that this should be RecyclerView or at least ListView with proper Adapter, not ScrollView with fixed layout

答案2

得分: -1

你可以使用NestedScrollView。它完成了任务。

英文:

You can use NestedScrollView. It did the job.

答案3

得分: -1

将您的 scrollView 放置在约束布局内,并将所有约束设置为父级。

英文:

Put your scrollView inside constraint layout and set all constraints to parent.

huangapple
  • 本文由 发表于 2020年8月21日 16:32:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/63519344.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定